%%% -*-texinfo-*-
%%% \magnification=\magstep1
%%%
%%% NOTE:  this texinfo file uses a modified version of texinfmt.el.
%%%   Before processing this file using texinfo-format-buffer you
%%%   should load this modified texinfmt.el, which should be in the
%%%   same directory as this file.
%%%
%%% ANOTHER NOTE: the e-lisp file "texstuff.el", also in this directory,
%%%   contains some Emacs functions which are useful in editing this file.
%%%   In particular, it contains functions for "texifying" example code
%%%   and for inserting #included example files, e.g. "example1.c".
%%%
\def\figure#1{\vskip 2.0truein
	      \special{psfile=#1 hscale=30.0 vscale=30.0
	      voffset=-50 hoffset=90}}
\tolerance=2000
\def\myfindex#1{\findex{\code{#1}}}
\def\panel#1{\emph{#1}}
\def\widget#1{\emph{#1}}
\def\object#1{\emph{#1}}
\def\caption#1{\centerline{{\bf{#1}}}}
\input psfig
\input texinfo
@setfilename geomview
@settitle Geomview Manual
@c
@titlepage
@sp 1
@center @titlefont{Geomview Manual}
@sp 4
@center Geomview Version 1.4.1
@sp 1
@center for Silicon Graphics Workstations
@sp 1
@center November 20, 1993
@sp 2
@center Mark Phillips
@sp 4
@vskip 0pt plus 1filll
@center Copyright @copyright{} 1993, The Geometry Center

@end titlepage
@page

@node Top,What,,(DIR)

@menu
* What::		What is Geomview?.
* Authors::		The Authors of Geomview.
* Register::		Let Us Hear From You.
* Overview::		Overview of Geomview.
* Tutorial::		Introductory Tutorial.
* Interaction::		Interacting with Geomview.
* OOGL File Formats::	Formats for Geometry Input.
* Customization::	Modifying the behavior of Geomview.
* Modules::		Programs that use Geomview for graphics display.
* GCL::			gcl: the Geomview Command Language.
* Mathematica::		Mathematica Graphics in Geomview or RenderMan.
* Installation::	Installing Geomview on your computer.

* Function Index::	A node for each gcl function.
@end menu

@node What,Authors,Top,Top
@unnumbered What Is Geomview?

Geomview, pronounced
@tex
g\'e-om-view,
@end tex
@ifinfo
GE-om-view,
@end ifinfo
is an interactive program for viewing and manipulating geometric
objects, written by staff members of the Geometry Center.  It can be
used as a standalone viewer for static objects or as a display engine
for other programs which produce dynamically changing geometry.  It runs
on Silicon Graphics (SGI) IRIS workstatons and NeXT workstations.  This
manual describes SGI Geomview version 1.4.1.  Although we do not yet
have a manual for the NeXT version, much this of manual applies to that
version as well as to the SGI version.@refill

Geomview and this manual are available for free via anonymous ftp on the
Internet from host @file{geom.umn.edu} (IP address 128.101.25.35).
Permission is granted to make copies of this manual.

If you have questions or comments about Geomview or this manual, you can
email them to @file{software@@geom.umn.edu}.  We are always glad to hear
from users.  There is also a @file{geomview-users} mailing list for
announcements regarding Geomview and for Geomview users to communicate
with each other.  If you use Geomview please send an email note to
@file{geomview-users-request@@geom.umn.edu} requesting to be added to
this mailing list.@refill

@node Authors,Register,What,Top
@unnumberedsec Authors

Tamara Munzner, Stuart Levy, and Mark Phillips are the original authors
of Geomview. Celeste Fowler, Charlie Gunn, and Nathaniel Thurston also
made significant contributions.  Daniel Krech and Scott Wisdom did the
NeXTStep and RenderMan port, and Daeron Meyer is currently working on a
port to X windows.

Mark Phillips wrote this manual, with substantial help from Stuart Levy
and Tamara Munzner.  Countless Geomview users have also been of great
help by reading it and pointing out mistakes.

@node Register,Overview,Authors,Top
@unnumbered Let Us Hear From You
We are very interested in hearing about how you are using Geomview.
Think of Geometry Center software as a new kind of shareware: you share
your science and successes with us, and we share our software and
support with you.  The Geometry Center is funded by the National Science
Foundation, and it is important that we be able to report to NSF the
ways in which our software is being used.

If you use Geomview, please send us a letter telling us what you are
doing with it. We need to know:

@enumerate
@item
What you are working on - an abstract of your work would be fine.

@item
How Geomview has helped you, for example, by increasing your
productivity or allowing you to do things you could not do before.  In
particular, if you feel that Geomview has had a direct bearing on your
work, please tell us about this.
@end enumerate

Please send the letter either via email to @code{register@@geom.umn.edu},
or via regular mail to the address below.

Moreover, if you use Geomview or other Geometry Center software in your
work, we encourage you to cite its use in your publications.

Thank you!



@example
Software Development Group
Geometry Center
1300 South 2nd St, Suite 500
Minneapolis, MN  55454
USA
@end example

@comment
@comment @node node-name, next, previous, up
@comment

@comment ****************************************************************
@node Overview,Tutorial,Register,Top
@chapter Overview

Geomview's main purpose is to display objects whose geometry is given,
allowing interactive control over details such as point of view, speed
of movement, appearance of surfaces and lines, and so on.  Geomview can
handle any number of objects and allows both separate and collective
control over them.  

The simplest way to use Geomview is as a standalone viewer to see
and manipulate objects.  It can display objects described in a variety
of file formats.  It comes with a wide variety of example objects, and
you can create your own objects.

You can also use Geomview to handle the display of data coming from
another program that is running simultaneously.  As the other program
changes the data, the Geomview image reflects the changes.  Programs
that generate objects and use Geomview to display them are called
@emph{external modules}.  External modules can control almost all
aspects of Geomview.  The idea here is that many aspects of the display
and interaction parts of geometry software are independent of the
geometric content and can be collected together in a single piece of
software that can be used in a wide variety of situations.  The author
of the external module can then concentrate on implementing the desired
algorithms and leave the display aspects to Geomview.  Geomview comes
with a collection of sample external modules, and this manual describes
how to write your own.

Geomview represents the current state of an ongoing effort at the
Geometry Center to provide interactive geometry software that is
particularly appropriate for mathematics research and education.  In
particular, Geomview can display things in hyperbolic and spherical
space as well as Euclidean space.

Geomview allows multiple independently controllable objects and
cameras.  It provides interactive control for motion, appearances
(including lighting, shading, and materials), picking on an object,
edge or vertex level, snapshots in SGI image file or Renderman RIB
format, and adding or deleting objects is provided through direct
mouse manipulation, control panels, and keyboard shortcuts.

Geomview supports the following simple data types: polyhedra with
shared vertices (.off), quadrilaterals, rectangular meshes, vectors,
and Bezier surface patches of arbitrary degree including rational
patches. Object hierarchies can be constructed with lists of objects
and instances of object(s) transformed by one or many 4x4 matrices.
Arbitrary portions of changing hierarchies may be transmitted by
creating named references.

Geomview can display Mathematica graphics output.

@comment ****************************************************************
@node Tutorial,Interaction,Overview,Top
@chapter Tutorial

This chapter leads you through some of the basics of using Geomview.
Work through this chapter in front of a workstation where you can try
out the examples given here to get a feel for what you can do with
Geomview.

To start Geomview, login to the computer and get a shell window.  A
shell window is a window in which you can type unix commands; the prompt
in the window usually ends with a '%'.  In the shell window (the mouse
cursor must be in the window) type the following (@kbd{@key{RET}} here
means hit the "Enter" key):

@example
geomview tetra dodec @key{RET}
@end example

This command starts up Geomview and loads two example objects, a
tetrahedron and a dodecahedron.  After a few seconds three windows
should appear as shown in Figure 1.
@ifinfo
(The figures in this document appear only in the hardcopy version,
not the Info version.)
@end ifinfo
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/initial.ps}}
\caption{Figure 1: Initial Geomview display}
}\endinsert
@end tex

The panel on the left is Geomview's main control panel; it's called
the @panel{Main} panel.  The skinny panel in the middle is the
@panel{Tools} panel and is for selecting different kinds of motions.
The window on the right is the camera window and in it you see a
large tetrahedron and a dodecahedron which is partially obscured
by the tetrahedron.

Geomview has lots of panels but by default it displays only these three.
We'll describe some aspects of these and a couple of the others in this
tutorial.  You can read more about these and other panels in the later
chapters of this manual.

Put the mouse cursor in the camera window and press down and hold the
left mouse button.  Now, while holding down the button, slowly move the
mouse around.  You should see the picture rotate in the direction you
move the mouse.    If you lift up on the mouse button while moving the
mouse, the picture continues rotating.  To stop it, hold the mouse very
still and click down and up on the left mouse button.

Geomview uses the @emph{glass sphere} model for mouse-based motion.  This
means you are supposed to think of the object as being inside an
invisible sphere and the mouse cursor is a gripper outside the sphere.
When you hold down the left mouse button, the gripper grabs the
sphere; when you let go of the button, the gripper releases the
sphere.  Moving the mouse while holding the button down causes the
sphere (and hence the object) to move in the same direction as the
mouse.

In addition to the two solids you should also see two wireframe
boxes in the camera window.  These are the "bounding boxes" of the two
objects.  By default Geomview puts a bounding box around each object
that it displays so that you have an idea of how large it is.

Notice that as you move the mouse around the tetrahedron and
dodecahedron move as a unit.  That is because by default what you are
actually moving is the "World".  To move an individual object instead of
the whole world, move the mouse cursor to the @widget{TARGET} browser in
the @panel{Main} panel.  Click (any button) on the word @widget{tetra}.
This makes the tetrahedron be the "target object".  Now move the cursor
back to the camera window and you can rotate just the tetrahedron.

The motion that you have been applying up to now has been rotation,
because that is the motion mode that is selected in the @panel{Tools}
panel.  To translate instead, click on the @widget{Translate} button.
Now when you move the mouse in the camera window while holding down the
left button, the tetrahedron (which should still be the target object
from before) will translate in the direction you move the mouse.  Notice
that you can translate it beyond the edge of the window as long as you
keep holding the left mouse button down.  If you lift up on the mouse
button while moving the mouse, the tetrahedron will keep going.  It
moves rather rapidly so it is very easy to lose track of where it is.

If you accidentally lose the tetrahedron by translating it too far out
of the view of the window, you can get it back by clicking on the
@widget{Center} button in the @panel{Tools} panel.  This causes it to
come back to its initial position.

Click on the @widget{Center} button to bring the tetrahedron home, and
then translate it off to one side so that you can completely see the
dodecahedron.

Your world now has two objects in it that are beside each other.  You
should see the dodecahedron in the middle of the window and maybe part
of the tetrahedron off to one side.  Go back to the @widget{TARGET}
browser in the @panel{Main} panel and click on "World" to select the
whole world again.  Now click on the @widget{Look At} button in the
@panel{Tools} panel.  You should see something like Figure 2 --- the
dodecahedron and the tetrahedron in the middle of the window next
to each other.  The @panel{Look At} button positions the camera in
such a way that the target object is centered in the window.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/fig2.ps}}
\caption{Figure 2: Looking at the world}
}\endinsert
@end tex

Now put the cursor over the middle of the dodecahedron and double-click
the right mouse button.  This means click it down-and-up two times in
rapid succession.  Notice that the dodecahedron becomes the target
object; you can see this in the @widget{TARGET} browser in the
@panel{Main} panel.  Double-clicking the right mouse button on an object
is another way to make it the target object.

Go to the @widget{PANELS} browser in the @panel{Main} panel and click on
the word @panel{Appearance}.  This brings up the @panel{Appearance}
panel.  When it appears, if it partially obscures another Geomview window
you can move it off to one side by dragging its frame with the middle
mouse button down.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/ap.ps}}
\caption{Figure 3: The Appearance Panel}
}\endinsert
@end tex

The @panel{Appearance} panel lets you control various things about the
way Geomview draws objects.  In the upper right corner, under the
@widget{Done} button are buttons labeled @widget{[af] Faces} and
@widget{[ae] Edges}.  Click on the @widget{[ae] Edges} one, and notice
that Geomview is now drawing the edges of the dodecahedron.  Click on it
again and the edges go away.  Click several times and watch the edges
come and go.  When you've had enough of this, leave the edges on
and click the @widget{[af] Faces} button.  This toggles the faces
on and off.  Click the button again to turn them back on.

Now click on the @widget{[Cf] Faces} button under the word
@widget{COLOR}.   A color chooser panel like the one in Figure
4 should appear.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/color.ps}}
\caption{Figure 4: Color Chooser Panel}
}\endinsert
@end tex
Put the cursor in the color hexagon in this panel and hold down the left
mouse button.  Slowly move the mouse around.  This drags the little
black point around to choose a new color for the dodecahedron.  The
previous colors were specified in the file @file{dodec} that you loaded
when we started Geomview.  The color that you specify with the color
panel overrides the old colors.  You can adjust the intensity of the
color with the @widget{Intensity} slider.  When you find a color that
you like, click the @widget{OK} button.


Now put the cursor somewhere over the gray background and double-click
the right mouse button; this picks "World" as the target object.
Click the @widget{Look At} button to look at the world again.

Notice that in the @panel{Appearance} panel the settings of the buttons
have changed from the way you left them with the dodecahedron.  That's
because the @panel{Appearance} panel always displays the settings for
the target object, which is now the world, which still has its
default settings.

Click on the @widget{[ab] BBox} button under the word @widget{Draw}.
The bounding boxes go away.  Now put the cursor back in the camera
window.  At the keyboard, type the keys @kbd{a b}.  Notice that the
bounding boxes come back.  @kbd{a b} is the keyboard shortcut for
the bounding box toggle button; the string "[ab]" appears on the
button to indicate this.  Most of Geomview's buttons have keyboard
shortcuts that you can use instead if you want.  This is useful once
you are familiar with Geomview and don't want to have to move around
among lots of panels.

Now select the tetrahedron, either by double-clicking the right mouse
button on it, or by selecting "tetra" in the @widget{TARGET} browser.
Then click on the @widget{Delete} button in the @panel{Main} panel.  The
tetrahedron should disappear.  This is how you get rid of an object.

You can also load objects from within Geomview.  Click on the @widget{Load}
button in the main panel.  The @panel{Files} panel will appear.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/secondlinelist.ps}}
\caption{Figure 5: The Files Panel}
}\endinsert
@end tex
Near the top of this panel is a browser with three lines in it; the
second line is a directory with lots of Geomview example files
in it.  Click on that second line.  Your @panel{Files} panel should
then look something like Figure 5.  Scroll down in the list of files
until you see @file{tref.off}.  Click on that line, and then click
on the @widget{Add} button.  A large trefoil-shaped tube will appear
in your window.  Click the @widget{Done} button in the @panel{Files}
panel to dismiss the panel.

@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/trefdodecinter.ps}}
\caption{Figure 6: Trefoil and Dodecahedron}
}\endinsert
@end tex

Now click on the @widget{Reset} button in the @panel{Tools} panel.  This
causes everything to return to its home position.  You should see
something like Figure 6 at this point: a dodecahedron and a
trefoil knot.

Play around with the trefoil knot and the dodecahedron.  Experiment with
some of the other buttons in the @panel{Tools} panel.  Try coloring the
trefoil knot with the @panel{Appearance} panel.

For a tutorial on how to create your own objects to load into Geomview,
see file @file{doc/oogltour} distributed with Geomview
(@file{/u/gcg/ngrap/doc/oogltour} on the Geometry Center system).  The
things in that file will be incorporated into a future version of this
manual.


@comment ****************************************************************
@node Interaction,Starting Geomview,Tutorial,Top
@chapter Interaction

This chapter describes how you interact with Geomview through the
mouse and keyboard.

@menu
* Starting Geomview::             Starting Geomview.
* Command Line Options::          Command Line Options.
* Basic Interaction::             Basic Interaction: The Main Panel.
* Loading::                       Loading Objects Into Geomview.
* Mouse Motions::                 Using the Mouse to Manipulate Objects.
* Appearance::                    Changing the Way Things Look.
* Cameras::                       Cameras.
* Saving::                        Saving your work.
* Command Obscure::               The Commands and Obscure Panels.
* Keyboard Shortcuts::            Keyboard Shortcuts.
@end menu

@comment ================================================================
@node Starting Geomview,Command Line Options,Interaction,Interaction
@section Starting Geomview

The usual way to start Geomview is to type @kbd{geomview @key{RET}} in a shell
window (RET means hit the "Enter" key).  It may take Geomview a few
seconds to start up; one or more windows will appear and you can begin
interacting with Geomview immediately.

It is also possible to specify actions for Geomview to perform at
startup time by giving arguments in the shell command line.
@xref{Command Line Options}.


@comment ================================================================
@node Command Line Options,Basic Interaction,Starting Geomview,Interaction
@section Command Line Options

Here are the command line options that Geomview allows:

@table @samp
@item -b @var{r} @var{g} @var{b}
Set the window background color to the given @var{r} @var{g} @var{b}
values.

@item -c @var{file}
Interpret the gcl commands in @var{file}, which may be the special
symbol @file{-} for standard input.  For a description of gcl,
@xref{GCL}.

@item -c @var{command}
Commands may also be supplied literally, as in
@example
-c "(ui-panel main off)"
@end example
Since @var{command} includes parentheses, which have special meaning to
the shell, @var{command} must be quoted.

@item -wins @var{nwins}
Causes Geomview to initially display @var{nwins} camera windows.

@item -wpos @var{width},@var{height}[@@@var{xmin},@var{ymin}]
Specifies the initial location and size of the first camera window.  The
values for @var{width}, @var{height}, @var{xmin}, and @var{ymin} are in
screen (pixel) coordinates.

@item -wpos @var{-}
You are prompted for placement of the first camera window.

@item -M @var{objectname}
Display (possibly dynamically changing) geometry sent from the
@code{geomstuff} program.  This actually listens to the
named pipe @file{/tmp/geomview/objectname}; you can achieve the same
effect with the shell commands:
@example
mkdir /tmp/geomview
mknod /tmp/geomview/objectname p
@end example
(assuming the directory and named pipe don't already exist), then
executing the gcl command:
@code{(geometry objectname  < /tmp/geomview/objectname)}

@item -Mc @var{pipename}
Like @samp{-M} above, but expects gcl commands, rather than OOGL
geometry data, on the connection.

@item -nopanels
Start up displaying no panels, only graphics windows.  Panels may be
invoked later as usual with the @kbd{Px} keyboard shortcuts or with
the @code{ui-panel} command.

@item -e @var{module}
Start an external module; @var{module} is the name associated with the
module, appearing in the main panel's Applications browser, as defined
by the @code{emodule-define} command.

@item -start @var{module} @var{args} @dots{}
Like -e but allows you to pass arguments to the external module.  "--"
signals the end of the argument list; the "--" may be omitted if it
would be the last argument on the Geomview command line.

@item -run @var{shell-command} @var{args} @dots{}
Like -start but takes the pathname of executable of the external module
instead of the module's name.

@end table

@comment ================================================================
@node Basic Interaction,Loading,Command Line Options,Interaction
@section Basic Interaction: The Main Panel

Normally when you invoke Geomview, three windows appear: the
@panel{Main} panel, the @panel{Tools} panel, and one camera window.
Geomview has many other windows but most things can be done with these
three and so by default the others do not appear.  This section of the
manual introduces some basic concepts that are used throughout the rest
of the manual and describes the @panel{Main} panel.

@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/main.ps}}
\caption{The Main Panel}
}\endinsert
@end tex

Geomview can display an arbitrary number of objects simultaneously.  The
@widget{TARGET} browser in the @panel{Main} panel displays a list of all
the objects that Geomview currently knows about.  This browser has a
line for each object that you have loaded, plus some lines for other
objects.  One of the other objects is called @code{World} and corresponds to
the all the currently loaded objects, treated as if they were one
object.  Most of the operations that you can do to one object, such as
applying a motion or changing a color, can also be done to the "World"
object.

The @widget{TARGET} browser also has an entry for each camera.  By
default there is only one camera; it is possible to add more of them via
the @panel{Camera} panel.  Geomview treats cameras in much the same way
as it does geometric objects.  For example, you can move cameras around
and add them and delete them just as with geometric objects.  Cameras do
not usually show up in the display as an object that you see.  Each
camera has a separate camera window which displays the view as seen by
that camera.  (It is possible for each camera to display a geometric
representation of other cameras; @xref{Cameras}.)

Because Geomview treats cameras and geometric objects very similarly,
the term @dfn{object} in this documentation is used to refer to either
one.  When we need to distinguish between the two kinds of objects, we
use the term @dfn{geom} to denote a geometric object and the word
@dfn{camera} to denote a camera.

The object which is selected (highlighted) in the @widget{TARGET}
browser is called the @dfn{target} object.  This is the object that
receives any actions that you do with the mouse or keyboard.  You can
change the target object by selecting a different line in the
@widget{TARGET} browser.  Another way to change the target object is
to put the mouse cursor directly over a geom in a camera window
and rapidly double-click the right mouse button.  This process is called
@dfn{picking}; the picked object becomes the new target.

Geomview objects are all known by two names, both of which are shown in
the @widget{TARGET} browser.  The first name given there, which appears
in square brackets ([ ]), is a short name assigned by Geomview when you
load the object.  It consists of the letter `g' for geoms and `c' for
cameras, followed by a number.  The second name is a longer more
descriptive name; by default this is the name of the file that the
object was loaded from.  The two names are equivalent as far as Geomview
is concerned; at any point where you need to specify a name you can give
either one.

To manipulate an object, make sure you that the object you want to move is the
target object, and put the mouse cursor in a camera window.  Motions are
applied by holding down either the left or middle mouse button and
moving the mouse.  There are several different motion "modes", each for
applying a different kind of motion.  The @widget{MOTION MODE} browser
in the @panel{Main} panel indicates the current motion mode.  The
default is "Rotate".  You can change the current motion mode by
selecting a new one in the @widget{MOTION MODE} browser, or by using the
@panel{Tools} panel.  For more information about motion modes,
@xref{Mouse Motions}.

The @widget{Load} button on the @panel{Main} panel brings up the
@panel{Files} panel for loading a file.  The file can contain either a
geom, a camera, or gcl commands.  For details, @xref{Loading}.

The @widget{Delete} button causes the target
object to be deleted.  Geomview selects another object to be the new
target.  You can delete cameras as well as geoms in this way.  If you
hit the @widget{Delete} button while the target object is "World",
Geomview deletes all geoms.

The @widget{Panels} browser on the @panel{Main} panel lists all the
Geomview panels.  Click on a panel's entry to bring that panel up.

The @widget{Modules} browser lists Geomview external modules.  An
external module is a separate program that interacts with Geomview to
extend its functionality.  For information on external modules,
@xref{Modules}.

The three buttons at the bottom of the @panel{Main} panel, labeled
@widget{Euclidean}, @widget{Hyperbolic}, and @widget{Spherical}, allow
you to change the geometry of the space that Geomview displays.  By
default @widget{Euclidean} is selected.  For details about using
@widget{Hyperbolic} and @widget{Spherical} spaces, @xref{Non-Euclidean
Geometry}.

Most actions that you can do through Geomview's panels have equivalent
keyboard shortcuts so that you can do the same action by typing a
sequence of keys on the keyboard.  This is useful for advanced users who
are familiar with Geomview's capabilities and want to work quickly
without having to have lots of panels cluttering up the screen.
Keyboard shortcuts are usually indicated in square brackets ([ ]) near
the corresponding item in a panel.  For example, the keyboard shortcut
for @widget{Rotate} mode is 'r'; this is indicated by "[r]" appearing
before the word "Rotate" in the @widget{MOTION MODE} browser.  To
use this keyboard shortcut, just hit the @kbd{r} key while the mouse
cursor is in any Geomview window.  Do not hit the @kbd{@key{RET}} key
afterwards.

Some keyboard shortcuts consist of more than one key.  In these cases
just type the keys one after the other, with no @kbd{@key{RET}}
afterwards.  Keyboard shortcuts are case sensitive.

The @widget{keyboard} field in the upper left corner of the @panel{Main}
panel echos the current state of keyboard shortcuts.

The button labeled @widget{?} near the top right corner of the
@panel{Main} panel causes Geomview to print out a list of all keyboard
shortcuts to standard output.

The @widget{Quit} button on the main panel terminates Geomview.


@comment ================================================================
@node Loading,Mouse Motions,Basic Interaction,Interaction
@section Loading Objects Into Geomview

There are several ways to load an object into Geomview.

@table @asis
@item the @panel{Files} panel
If you click the @widget{Load} button in Geomview's @panel{Main} panel,
the @panel{Files} panel will appear. 

@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/myfilelist.ps}}
\caption{The Files Panel}
}\endinsert
@end tex
This panel lets you select a file from a variety of directories.
The short browser at the top of the panel shows the selected directory,
and the longer browser beneath it shows the files in that directory.  To
select a file, click on it.  After a file is selected, you can load it
into Geomview by clicking either the @widget{Add} or @widget{Replace}
button.  The @widget{Add} button causes Geomview to load the file as a
new object; a new entry will appear in the @widget{Objects} browser in
the @panel{Main} panel, and all objects currently loaded will remain
unchanged.  The @widget{Replace} button causes Geomview to replace the
current object with the object in the selected file.  If the current
object is the @object{World}, Geomview deletes all objects and loads the
one in the file as a new object.  If the current object is a camera, the
@widget{Replace} button has no effect.@refill

If the file that you select contains gcl commands rather than an
OOGL object, the @widget{Add} and @widget{Replace} buttons both cause
Geomview to interpret the commands in the file.  For more information
about this, @xref{GCL}.

When the @panel{Files} panel first appears, the directory selected in the
directory browser is the current directory --- the one from which you
invoked Geomview.  The file browser shows @emph{all} the files in this
directory, including ones that are not Geomview files.  If you try to
load a file that doesn't contain either an OOGL object or Geomview
commands, Geomview will print out an error message.

The directory browser also lists a second and third directory in
addition to the current directory.  The second one, which ends in
@file{data/geom}, is the Geomview example data directory.  This contains
a wide variety of sample objects.  It also contains several
subdirectories.  In particular, the @file{hyperbolic} and
@file{spherical} subdirectories have sample hyperbolic and spherical
objects, respectively.  Directory entries in the browser look just like
file entries; to view a subdirectory, click on it.

The third directory shown in the directory browser, which ends in
@file{geom}, contains several subdirectories with other Geomview files
in them.  These are used less frequently than the ones in the
@file{data/geom} directory.

You can change the list of directories shown the @panel{Files}
panel's directory browser by using the @code{set-load-path} command;
@pxref{GCL}.

@item the @kbd{<} keyboard shortcut:
If you type @kbd{<} in any Geomview window, the @panel{Load} panel will
appear.  This is a small version of the @panel{Files} panel; it contains
a text field in which you can enter the name of a file to load.  After
typing the name of the file to load, type @kbd{@key{RET}}; Geomview will
load the file as if you had loaded it with the @widget{Add} button in
the @panel{Files} panel.  If, after bringing up the small load panel
with @kbd{<}, you decide you want to use the larger @panel{Files} panel
after all, press the @widget{Files Browser} button.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/load.ps}}
\caption{The Load Panel}
}\endinsert
@end tex

@item geometry loading commands:
The @code{load}, @code{geometry}, @code{new-geometry}, and @code{read}
gcl commands allow you to load an object into Geomview;
@xref{GCL}.@refill

@end table

@comment ================================================================
@node Mouse Motions,Point of Interest,Loading,Interaction
@section Using the Mouse to Manipulate Objects

Geomview lets you manipulate objects with the mouse.  There are six
different mouse motion modes: @widget{Rotate}, @widget{Translate},
@widget{Cam Fly}, @widget{Cam Zoom}, @widget{Geom Scale}, and
@widget{Cam Orbit}.  The tools panel has a button for each of these
modes; to switch modes, click on the corresponding button.  You can also
select these through the @widget{Motion Mode} browser on the
@panel{Main} panel.@refill

This section describes basic mouse interaction.  There are some more
advanced features available on the @panel{Obscure} panel.  For details,
@pxref{Command Obscure}.

@tex
\midinsert
\vbox{
\centerline{\psfig{file=figs/tools.ps}}
\caption{The Tools Panel}
}
\endinsert
@end tex

Each of the motion modes uses a common paradigm for how the motion is
applied.  In particular, each depends on the current @emph{target}
object and the current @emph{center} object.  These are explained in the
following paragraphs.

The current target object is shown in the @widget{Target} field in the
@panel{Tools} panel.  This is the same as the selected object in the
@widget{TARGET OBJECTS} browser in the @panel{Main} panel, and you can
change it by either selecting a new object in the browser, by typing
a new entry in the field, or by picking an object in a camera
window by double-clicking the right mouse button with the cursor over
the object.

The current center object is shown in the @widget{Center} field in the
@panel{Tools} panel.  Its default value is the special word "target",
which means that the center object is whatever the target object is.
You can change the center to any object by typing it in the @widget{Center}
field.  The origin of the center object is held fixed in @widget{Rotate} and
@widget{Orbit} modes.  Normally the center object is one of the existing
geoms listed in the @widget{TARGET OBJECTS} browser, and the actual center of
rotations is the origin of that object's coordinate system.
It is possible, however, to select an arbitrary point of interest on
an object as the center. For details, @pxref{Point of Interest}.

You apply a mouse motion by holding down either the left or middle mouse
button with the cursor in a camera window and moving the mouse.  Most of
the modes have @emph{inertia}, which means that if you let go of the
button while moving the mouse, the motion will continue.  It may be
helpful to imagine the mouse cursor as being a gripper; when you hold a
mouse button down, it grips the target object and you can move it.  When
you let go of the mouse button, the gripper releases the object.
Letting go of the mouse button while moving the mouse is like throwing
the object --- the object continues moving independent of the mouse.
Inertia can be turned off; see the button on the @panel{Obscure} panel.

Most of the mouse motions have a slow motion version which you get by
holding down the shift key while doing the motion as usual.  This
is useful for finer control.

You can pick any point on an object (not just its origin) as the center of
motion by holding down the shift key while clicking the right mouse button;
this chooses a point of interest.

@table @widget

@item Rotate
In @widget{Rotate} mode, hold the left mouse button down to rotate the
target object about the center object.  Rotation proceeds in the
direction that you move the mouse.  Specifically, the axis of rotation
passes through the origin of the center object, is parallel to the
camera view plane, and is perpendicular to the direction of motion of
the mouse.  When the center is "target", this means that the target
object rotates about its own origin.

The middle mouse button in @widget{Rotate} mode rotates the target
object about an axis perpendicular to the view plane.

@item Translate
In @widget{Translate} mode, hold the left mouse button down to translate
the target object in the direction of mouse motion.  The middle mouse
button translates the target along an axis perpendicular to the view
plane.

In Euclidean space, the center object is essentially irrelevant for
translations.  In hyperbolic and spherical spaces, where translations
have a unique axis, this axis is chosen to go through the origin of the
center object.

@item Cam Fly
@widget{Cam Fly} is a crude flight simulator that lets you fly around
the scene.  It works by moving the camera.
Move the mouse while holding the left mouse button down to
point the camera in a different direction.  To move forward or backward,
hold down the middle button and move the mouse vertically.  Both of
these motions have inertia; typically the easiest way to fly around a
scene is to give the camera a slight forward push by letting go of the
middle button while moving the mouse upward, and then using the left
button to steer.

@widget{Cam Fly} affects the camera window that the mouse is in; it
ignores the target object and the center object.

@item Cam Orbit
@widget{Cam Orbit} mode lets you rotate the current camera around the
current center. The left mouse button does this rotation.  The middle
mouse button in @widget{Cam Orbit} mode is the same as it is in
@widget{Cam Fly} mode: it moves the camera forward or backward.

In general @widget{Cam Orbit} does not move the target object, although
if the current camera is selected as the target and the center is also
the target, it will rotate that camera about itself just as in
@widget{Cam Fly} mode.

@item Cam Zoom
@widget{Cam Zoom} mode lets you change the current camera's field of
view with the mouse; hold the left mouse button down and move the mouse
to change it.  The numeric value of the field of view is shown in the
@widget{FOV} field in the @panel{Camera} panel.

@item Geom Scale
@widget{Geom Scale} mode lets you enlarge or shrink a geom.  It operates
on the target object if that object is a geom.  If the target is a
camera, @widget{Geom Scale} operates on the geom that was most recently
the target object.  Moving the mouse while holding down the left mouse button
scales the object either up or down, depending on the direction of
mouse motion.  The center of the applied scaling transformation is the
center object.

Scaling is meaningful only in Euclidean space; attempts to scale are
ignored in other spaces.


@widget{Geom Scale} mode does not have inertia.

@end table

The @widget{Stop}, @widget{Look At}, @widget{Center}, and @widget{Reset}
buttons on the @panel{Tools} panel perform actions related to motions
but do not change the current motion mode.


@table @widget

@item Stop
The @widget{Stop} button causes all motions to stop.  It affects all
moving objects; not just the target object.  It's keyboard shortcut
is @kbd{H}.

The keyboard command @kbd{h}, which does not correspond to a
panel button, stops the current motion for the target object only.

@item Look At
The @widget{Look At} button causes the current camera to be moved
to a position such that it is looking at the target object, and such
that the target object more or less fills the window.

The Look At command is unreliable in non-Euclidean spaces.

@item Center
The @widget{Center} button undoes the target object's transformation,
moving it back to its home position, which is where it was when you
originally loaded it into Geomview.

@item Reset
The @widget{Reset} button stops all motion and causes all objects to
move back to their home positions.

@end table

The other four buttons on the @panel{Tools} panel are:

@table @widget

@item MAIN
This button brings up the @panel{Main} panel in case you have dismissed it
or in case it is buried underneath other panels.

@item Done
This button dismisses the @panel{Tools} panel.  You can bring the panel
back by selecting it in the @widget{More Panels} browser in the @panel{Main}
panel, or via the @kbd{P t} keyboard shortcut.

@item Load
This is the same as the @widget{Load} button on the @panel{Main} panel;
it brings up the @panel{Files} panel.

@item Save
This is the same as the @widget{Save} button on the @panel{Main} panel;
it brings up the @panel{Save} panel.

@end table

@comment ================================================================
@node Point of Interest,Appearance,Mouse Motions,Mouse Motions
@subsection Selecting a Point of Interest

It is sometimes useful to specify a particular point on some object in a
geomview window as the center point for mouse motions.  You can do this
by shift-clicking the right mouse button (i.e. click it once
while holding down the shift key on the keyboard) with the cursor over
the desired point.  This point then becomes the @emph{point of
interest}.  The point of interest must be on an existing object.

Selecting a point of interest simplifies examining a small portion of a
larger object.  Shift-right-click on an interesting point, and select
@widget{Orbit} mode.  Use the middle mouse button to approach, and the
left mouse to orbit the point, examining the region from different
directions.

When you have selected a point of interest, the current center object
changes to an object named "CENTER", which is an invisible object
located at the point of interest.  In addition, mouse motions for the
window in which you made the selection are adjusted so that the point of
interest follows the mouse.

You can change the point of interest at any time by selecting a new one
by shift-clicking the right mouse button again.  You can cancel
the point of interest altogether by shift-clicking the right
mouse button with the cursor on the background (i.e. not on any object).
This changes the center object back to its default value, "target".

The object named "CENTER", which serves as the center object for the
point of interest, is a special kind of geom called an "alien".  It does
not appear in the @widget{TARGET OBJECTS} browser.  By default it has no
geometry associated with it and hence is invisible.  You can, however,
explicitly give it some geometry using a GCL command, causing it to
appear.  Use the @code{geometry} command for this: @code{(geometry
CENTER @var{geometry})}, where @var{geometry} is any valid geometry.
For example, @code{(geometry CENTER @{ < xyz.vect @})} causes the file
@file{xyz.vect}, which is one of the standard example files distributed
with geomview, to be used at the geometry for CENTER.


What actually happens internally when you select a point of interest is
that the center is set to the object called CENTER, and that object is
positioned at the point of interest.  In addition, in order for mouse
motions to track the point of interest, the current camera's focal
length is set to be the distance from the camera to the point of
interest.  You can accomplish this via GCL with the following commands:
@example
(if (real-id CENTER) nil (new-alien CENTER {}))
(ui-center CENTER)
(transform-set CENTER universe universe translate @var{x} @var{y} @var{z})
(merge camera @var{cam-id} @{ focus @var{d} @})
@end example
@noindent
where @code{(@var{x},@var{y},@var{z})} are the (universe) coordinates of
the point of interest, and @var{d} is the distance from that point to
the current camera, @var{cam-id}.  The first command above creates the
"alien" CENTER if it does not yet exist.

@comment ================================================================
@node Appearance,Appearance Panel,Point of Interest,Interaction
@section Changing the Way Things Look

Geomview uses a hierarchy of appearances to control the way things look.
An @dfn{appearance} is a specification of information about how
something should be drawn.  This can include many things such things as
color, lighting, material properties, and more.  Appearances work in a
hierarchal manner: if a certain appearance property, for example face
color, is not specified in a particular object's appearance, that object
is drawn using that property from the parent appearance.  If both the
parent and the child appearance specify a property, the child's setting
takes precedence unless the parent appearance is set to override.

Every geom in Geomview has an appearance associated with it.  There is
also an appearance associated with the "World" geom, which serves as the
parent of each individual geom's appearance.  Finally, there is an
global "base" appearance, which is the parent of the World appearance.

The base appearance specifies reasonable values for all appearance
information, and by default none of the other appearances specify
anything, which means they inherit their values from the base
appearance.  This means that by default all objects are drawn using the
base appearance.

If you change a certain appearance property for a geom, that property
is used in drawing that geom.  The parent appearance is used for any
properties that you do not explicitly set.

Geomview has three panels which let you modify appearances.  

@menu
* Appearance Panel::	Color etc.
* Materials Panel::	Surface Material properites.
* Lighting Panel::	Lighting Parameters.
@end menu

@comment ----------------------------------------------------------------
@node Appearance Panel,Materials Panel,Appearance,Appearance
@subsection The Appearance Panel

The @panel{Appearance} panel lets you change most common appearance
properties of the target object.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/ap.ps}}
\caption{The Appearance Panel}
}\endinsert
@end tex
If the target is an individual geom, then changes you make in the
appearance panel apply to that geom's appearance.  If the target is the
World, then appearance panel changes apply to the World appearance
@emph{and} to all individual geom appearances.  (Users have found that
this is more desirable than having the changes only apply to the World
appearance.)  If the target is a camera, then appearance panel changes
apply to the geom that was most recently the target.

The five buttons near the upper right corner under the word
@widget{Draw} control what parts of the target geom are drawn.

@table @widget

@item Faces
This button specifies whether faces are drawn.

@item Edges
This button specifies whether edges are drawn.

@item BBox
This button specifies whether the bounding box is drawn.

@item Vects
This button specifies whether VECT objects are drawn.  VECTs are a type
of OOGL object that represent points and line segments in 3-space;
they are distinct from edges of other kinds of objects, and it is sometimes
desirable to have separate control over whether they are drawn.

@item Normals
This button specifies whether surface normal vectors are drawn.

@end table

The four buttons under @widget{COLOR} labeled @widget{Faces}, @widget{Edges},
@widget{Normals}, and @widget{BBox} let you specify the color of
the corresponding aspect of the target geom.  Clicking on one
of them brings up a color chooser panel.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/color.ps}}
\caption{Color Chooser Panel}
}\endinsert
@end tex
The black dot in the center of the hexagon represents the current color;
you can move it around by dragging it with the left mouse button down.
The slider specifies the intensity.  To accept the color that you have
chosen, click the @widget{OK} button.  To cancel your color selection
and return to the previous color, click the @panel{Cancel} button.

The @widget{SHADING} browser lets you specify the shading model that
Geomview uses to paint the target geom.

@table @widget

@item Constant
Every face of the object is drawn with a constant color which does not
depend on the location of the face, the camera, or the light sources.
If the object does not contain per-face or per-vertex colors, the
diffuse color of the object's appearance is used.  If the object
contains per-face colors, they are used.  If the object contains
per-vertex colors, each face is painted using the color of its first
vertex.

@item Flat
Each face of the object is drawn with a color that depends on the
relative location of the face, the camera, and the light sources.
The color is constant across the face but may change as the face,
camera, or lights move.

@item Smooth
Each face of the object is drawn with smoothly interpolated colors based
on the normal vectors at each vertex.  If the object does not contain
per-vertex normals, this has the same effect as flat shading.  If the
object has reasonable per-vertex normals, the effect is to smooth
over the edges between the faces.

@item CSmooth
Each face of the object is drawn with exactly the specified color(s),
independent of lighting, orientation, and material properties.  If the
object is defined with per-vertex colors, the colors are interpolated
smoothly across the face; otherwise the effect is the same as in
Constant shading style.

@end table

The @widget{Facing Normals} button on the @panel{Appearance} panel
indicates whether or not Geomview should arrange that normal vectors
always face the viewer.  If a normal vector points away from the viewer
the color of the corresponding face or vertex usually is darker than is
desired.  Geomview can avoid this by using the opposite normal in
shading calculations.  This is the default.  To change it so that the
actual normals are used, press this button.  This has no effect in
constant shading mode.

The three text fields in the lower left corner of the @panel{Appearance}
panel are:

@table @widget

@item Line Width
The width, in pixels, for lines drawn by Geomview.

@item Normal Length
This is actually a scale factor; when normal vectors are drawn, Geomview
draws them to have a length that is their natural length times this
number.

@item Patch Dicing
Geomview draws Bezier patches by first converting them to meshes.  This
parameter specifies the resolution of the mesh: if @widget{Patch Dicing}
is @var{n}, then an @var{n} by @var{n} mesh is used to draw each Bezier
patch.  if @widget{Patch Dicing} is 1, the resolution reverts to a
built-in default value.

@end table

The @widget{Revert} button on the @panel{Appearance} panel undoes all
settings in the target appearance.  This causes the target geom to
inherit all its appearance properties from its parent.

The @panel{Appearance} panel's @widget{Override} button determines whether
appearance controls should override settings in the objects themselves --
for example, setting the face color will affect all faces of objects with
multi-colored facets.  Otherwise, appearance controls only provide settings
which the objects themselves do not specify.
By default, @widget{Override} is enabled.  This button applies to all objects,
and to all appearance-related panels.

@comment ----------------------------------------------------------------
@node Materials Panel,Lighting Panel,Appearance Panel,Appearance
@subsection The Materials Panel

The @panel{Materials} panel controls material properties of surfaces.
It works with the target object in the same way that the
@panel{Appearance} panel does.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/mat.ps}}
\caption{The Materials Panel}
}\endinsert
@end tex

@table @widget

@item Transparent
This button determines whether transparency is enabled.  Geomview
does not fully support transparency yet and on some machines it does
not work at all.

@item Alpha
This slider determines the opacity/transparency when transparency is
enabled.  0 means totally transparent, 1 means totally opaque.

@item Diffuse Reflectance
This slider controls the diffuse reflectance of a surface.  This has
to do with how much the surface scatters light that it reflects.

@item Shininess
This slider controls how shiny a surface is.   This determines the
size of specular highlights on the surface.  Lower values give the
surface a duller appearance.

@item Ambient Reflectance
This slider controls how much of the ambient light a surface reflects.

@item Specular Reflectance
This slider controls the specular reflectance of a surface.  This
has to do with how directly the surface reflects light rays.  Higher
values give brighter specular highlights.

@item Done
This button dismisses the @panel{Materials} panel.

@end table

@comment ----------------------------------------------------------------
@node Lighting Panel,Cameras,Materials Panel,Appearance
@subsection The Lighting Panel

The @panel{Lighting} panel controls the number, position, and color of
the light sources used in shading.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/light.ps}}
\caption{The Lighting Panel}
}\endinsert
@end tex

The @panel{Lighting} panel is different from the @panel{Appearance} and
@panel{Material} panels in that it always works with the base
appearance.  This is because it usually makes sense to use the same set
of lights for drawing all objects in your scene.

@table @widget

@item LIGHTS
The @widget{LIGHTS} browser shows the currently selected light.  Changes
made using the other widgets on this panel apply to this light.  There
is always at least one light, the ambient light.

@item Intensity
This slider controls the intensity of the current light.

@item Color
This button brings up a color chooser which lets you select the color
of the current light.

@item Add
This button adds a light.

@item Delete
This button deletes the current light.

@item Show Lights
This button lets you see and change the positions of the light sources
in a camera window.  Each light is drawn as long cylinder which is
supposed to remind you of a light beam.  When you click on the
@widget{Show Lights} button Geomview goes into "light edit" mode, during
which you can rotate current light by holding down the left mouse button
and moving the mouse.  Lights placed in this way are infinitely distant,
so what you are changing is the angular position.  Click on the
@widget{Show Lights} button again to return to the previous motion mode
and to quit drawing the light beams.

@item Done
This button dismisses the @panel{Lighting} panel.

@end table

Geomview's @panel{Appearance}, @panel{Materials}, and @panel{Lighting}
panels are constructed to allow you to easily do most of the appearance
related things that you might want to do.  The appearance hierarchy that
Geomview supports internally, however, is very complex and there are
certain operations that you cannot do with the panels.  The Geomview
command language (gcl) provides complete support for appearance operations.
In particular, the @code{merge-baseap} command can be used to change the
base appearance (which, except for lighting, cannot be changed by
Geomview's panels).  The @code{merge-ap} command can be used to change
an individual geom's appearance.  Appearances can also be specified in
OOGL files; for details, @pxref{Appearances}.


@comment ================================================================
@node Cameras,Saving,Lighting Panel,Interaction
@section Cameras

A camera in Geomview is the object that corresponds to a camera window.
By default there is only one camera, but it is possible to have as many
as you want.  You can control certain aspects of the way the world is
drawn in each camera window via the @panel{Cameras} panel.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/cam.ps}}
\caption{The Cameras Panel}
}\endinsert
@end tex
If the target object is a camera, the @panel{Cameras} panel affects that
camera.  If the target object is not a camera, the @panel{Cameras} panel
affects the @dfn{current camera}.  The current camera is the camera of
the window that the mouse cursor is in, or was in most recently if the
cursor is not in a camera window.  Thus, if you use the keyboard
shortcuts for the actions in the @panel{Cameras} panel while the cursor
is in a camera window, the actions apply to that camera, unless you have
explicitly selected another camera.

@table @widget

@item Add Camera
Clicking on this button causes Geomview to create a new camera.  The
new camera's window appears, and an entry for it appears in the
@widget{TARGET} browser of the @panel{Main} panel.

@item Software Shading
This button controls whether Geomview does shading calculations in software.
The default is to let the hardware handle them, and in Euclidean space
this is almost certainly best because it is faster.  In hyperbolic and
spherical space, however, the shading calculations that the hardware
does are incorrect.  Click this button to turn on correct but slower
software shading.

@item Background Color
This button brings up a color chooser which you can use to set the
background color of the camera's window.

@item PROJECTION
This browser lets you pick between perspective and orthogonal projection
for this camera.

@item Near clip
This determines the distance in world coordinates of the near clipping
plane from the eye point.  It must be a positive number.

@item Far clip
This determines the distance in world coordinates of the far clipping
plane from the eye point.  It must be a positive number and in general
should be larger than the @widget{Near clip} value.

@item FOV
This is the camera's field of view, measured in its shorter direction.
In perspective mode, it is an angle in degrees.  In orthographic mode,
it is the linear size of the field of view.  This number can be modified
with the mouse in @widget{Cam Zoom} mode.

@item Focal Length
The focal length is intended to suggest the distance from the camera to
an imaginary plane of interest.  Its value is used when switching
between orthographic and perspective views (and during stereo viewing),
so as to preserve apparent size of objects lying at the focal distance
from the camera.

@item Lines Closer
This number has to do with the way lines are drawn.  Normally Geomview's
z-buffering algorithm can get confused when drawing lines that lie
exactly on surfaces (such as the edges of an object); due to machine
round-off error, sometimes the lines appear to be in front of the
surface and sometimes they appear behind it.  The @widget{Lines Closer}
value is a fudge factor --- Geomview nudges all the lines that it draws
closer to the camera by this amount.  The number should be a small
integer; try 5 or 10.  0 turns this feature off completely.  Choosing
too large a value will make lines visible even though they should be
hidden.

@item SPACE MODEL
This determines the model used to draw the world.  It is most useful in
hyperbolic and spherical spaces.  You probably don't need to touch this
browser if you stay in Euclidean space.  For more information about
these models, @pxref{Non-Euclidean Geometry}.
@table @widget
@item Virtual
This is the default model and represents the natural view from inside
the space.

@item Projective
The projective model of hyperbolic and spherical space.  Geoms move
under isometries of the space, and cameras move by Euclidean motions.
By default in the projective model, the Euclidean unit sphere is drawn.
In hyperbolic space this is the sphere at infinity.  In Euclidean space
the projective model is the same as the virtual model except that the
sphere is drawn by default.

@item Conformal
The conformal model of hyperbolic and spherical space.  Geoms move under
isometries of the space, and cameras move by Euclidean motions.  In
Euclidean space, the conformal model amounts to inverting everything in
the unit sphere.
@end table

@item Draw Sphere
This controls whether Geomview draws the unit sphere.  By default the
unit sphere appears in the projective and conformal models.  In
hyperbolic space this is the sphere at infinity.  In spherical space it
is the equatorial sphere.

@item Done
This button dismisses the @panel{Cameras} panel.

@end table

@comment ================================================================
@node Saving,Command Obscure,Cameras,Interaction
@section Saving your work

Geomview's @panel{Save} panel lets you store Geomview objects and other
information in files that you can read back into Geomview or other
programs.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/save.ps}}
\caption{The Save Panel}
}\endinsert
@end tex
To use the @panel{Save} panel you select the desired format in the
browser next to the word @widget{Save}, enter the name of the object you
want to save in the text field next to the word @widget{for}, and enter
the name of the file you wish to save to in the long text field next to
the word @widget{in}.  You can then either hit @kbd{@key{RET}} or click
on the @widget{OK} button.  When the file has been written, the @panel{Save}
panel disappears.  If you want to dismiss the @panel{Save} panel without
writing a file, click the @widget{Cancel} button.

If you specify @file{-} as the file name, Geomview will write the file
to standard output, i.e. in the shell window from which you invoked
Geomview.

The possible formats are given below.  The kind of object that can
be written with each format is given in parentheses.

@table @widget

@item Commands @asis{(any object)}
This write a file of gcl commands containing all information about
the object.  Loading this file later will restore the object as well as
all other information about it, such as appearance, transformations,
etc.

@item Geometry alone @asis{(geom)}
This writes an OOGL file containing just the geometry of the object.

@item Geometry [in world] @asis{(geom)}
This writes an OOGL file containing just the geometry of the object,
transformed under Geomview's current transformation for this object.
Use this if you have moved the object from its initial position and want
to save the new position relative to the world.

@item Geometry [in universe] @asis{(geom)}
This writes an OOGL file containing just the geometry of the geom,
transformed under both the object's transformaton and the world's
transformation.

@item RMan [->tiff] @asis{(camera)}
Writes a RenderMan file which when rendered creates a tiff image.

@item RMan [->frame] @asis{(camera)}
Writes a RenderMan file which when rendered causes an image to appear in
an Iris window.

@item SGI snapshot @asis{(camera)}
Write an SGI raster file.  A bell rings when the snapshot is complete.

@item Camera @asis{(camera)}
Writes an OOGL file of a camera.

@item Transform [to world] @asis{(any object)}
Writes an OOGL transform file giving Geomview's transform for the object.

@item Transform [to universe] @asis{(any object)}
Writes an OOGL transform file giving a transform which is the
composition of Geomview's transform for the object and the transform for
the world.

@item Window @asis{(camera)}
Writes an OOGL window file for a camera.

@item Panels
Writes a gcl file containing commands which record
the state of all the Geomview panels.  Loading this file later will
restore the positions of all the panels.

@end table

@comment ================================================================
@node Command Obscure,Keyboard Shortcuts,Saving,Interaction
@section The Commands and Obscure Panels

The @panel{Commands} panel lets you type in a gcl command.  When
you hit @kbd{@key{RET}}, Geomview interprets the command and prints any
resulting output or error messages on standard output.  You can edit the
text and hit @kbd{@key{RET}} as many times as you like, in general,
whenever you hit @kbd{@key{RET}} with the cursor in the @panel{Commands}
panel, Geomview tries to interpret whatever text you have typed in the
text field as a command.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/command.ps}}
\caption{The Commands Panel}
}\endinsert
@end tex

The @panel{Obscure} panel is for relatively obscure things that don't
really belong on any of the other panels.  In the present version of
Geomview, the @panel{Obscure} panel includes the @widget{NORMALIZE GEOMETRY}
browser, which controls the kind of geometry normalization that Geomview does,
and several buttons affecting motion style.
@tex
\midinsert\vbox{
\centerline{\psfig{file=figs/obscure.ps}}
\caption{The Obscure Panel}
}\endinsert
@end tex

Normalization is a kind of scaling; Geomview can scale an object so that
it fits within a certain region.  The main point of normalization is to
allow you to easily view all of an object without having to worry about
how big it is.  We are gradually replacing Geomview's normalization
feature with more robust camera positioning features.  In general, the
best way to make sure you are seeing all of an object is to use the
@widget{Look At} button on the @panel{Tools} panel.  Normalization may
be completely replaced by this and other features in a future version of
Geomview.

Normalization is a property that applies to each geom separately.  The
@widget{NORMALIZE GEOMETRY} browser affects the normalization property
of target geom.  If the target geom is "World", it affects all geoms.

@table @widget

@item None
Do no normalization.

@item Individual
Normalize this geom to fit within a unit sphere.

@item Sequence
This resembles "Individual", except when an object is changing.  Then,
"Individual" tightly fits the bounding box around the object whenever it
changes and normalizes accordingly, while "Sequence" normalizes the
union of all variants of the object and normalizes accordingly.

@item Keep
This leaves the current normalization transform unchanged when the
object changes.  It may be useful to apply "Individual" or "Sequence"
normalization to the first version of a changing object to bring
it in view, then switch to "Keep".

@end table

The @widget{Motion Style} controls include the following buttons.

@table @widget

@item [ui] Inertia
Normally, moving objects have inertia: if the mouse is still moving
when the button is released, the selected object continues to move.
When @widget{Inertia} is off, objects cease to move as soon as you release
the mouse.

@item [uc] Constrain Motion
It's sometimes handy to move an object in a direction aligned with a
coordinate axis: exactly horizontally or vertically.  Selecting
@widget{Constrain Motion} changes the interpretation of mouse motions
to allow this; approximately-horizontal or approximately-vertical mouse dragging
becomes exactly horizontal or vertical motion.  Note that the motion is
still along the X or Y axes of the camera in which you move the mouse,
not necessarily the object's own coordinate system.

@item [uo] Own Coordinates
It's sometimes handy to move objects with respect to the coordinate system
where they were defined, rather than with respect to some camera.  While
@widget{Own Coordinates} is selected, all motions are interpreted that way:
dragging the mouse rightward in translate mode moves the object in its own +X
direction, and so on.  May be especially useful in conjunction with
the @widget{Constrain Motion} button.

@end table


@comment ================================================================
@node Keyboard Shortcuts,OOGL File Formats,Command Obscure,Interaction
@section Keyboard Shortcuts

Most actions that you can do through Geomview's panels have equivalent
keyboard shortcuts so that you can do the same action by typing a
sequence of keys on the keyboard.  This is useful for advanced users who
are familiar with Geomview's capabilities and want to work quickly
without having to have lots of panels cluttering up the screen.
Keyboard shortcuts usually are indicated in square brackets ([ ]) near
the corresponding item in a panel.  For example, the keyboard shortcut
for @widget{Rotate} mode is 'r'; this is indicated by "[r]" appearing
before the word "Rotate" in the @widget{MOTION MODE} browser.  To
use this keyboard shortcut just hit the @kbd{r} key while the mouse
cursor is in any Geomview window.  Do not hit the @kbd{@key{RET}} key
afterwards.

Some keyboard shortcuts consist of more than one key.  In these cases
just type the keys one after the other, with no @kbd{@key{RET}}
afterwards.  Keyboard shortcuts are case sensitive.  You can cancel a
multi-key keyboard shortcut that you have started by typing any invalid
key, for example @kbd{^}.

Keyboard commands apply while the cursor is in any camera window and
most control panels.

Many keyboard shortcuts allow numeric arguments which you type as a
prefix to the command key(s).  For example, the shortcut for
@widget{Near clip} in the camera panel is @kbd{v n}.  To set the near
clip plane to "0.5", type @kbd{0.5 v n}.  Commands that don't take a
numeric prefix toggle or reset the current value.

Most commands allow one of the following selection prefixes.  If none is
provided the command applies to the target object.

@table @kbd
@item g
world geom	
@item g#
#'th geom
@item g*
All geoms
@item c
current camera
@item c#
#'th camera
@item c*
All cameras
@end table

For example, @kbd{g 4 a f} means toggle the face drawing of object
@widget{g4}.

The text field in the upper left corner of the @panel{Main} panel
shows the state of the current keyboard shortcut.

In addition to the keyboard shortcuts for the panel commands, there is
also a shortcut for picking a target object: type the short name of the
object followed by @kbd{p}.  For example, to select object @widget{g3},
type @kbd{g 3 p}.  This only works with the short names --- the ones
that appear in square brackets ([ ]) in the @widget{TARGET} browser of
the @panel{Main} panel.

Below is a summary of all keyboard shortcuts.

@table @asis
@item Draw
    @table @kbd
    @item af
    Faces
    @item ae
    Edges
    @item an
    Normals
    @item ab
    Bounding Boxes
    @item aV
    Vectors
    @end table
@item Shading
    @table @kbd
    @item 0as
    Constant
    @item 1as
    Flat
    @item 2as
    Smooth
    @item 3as
    Smooth, non-lighted
    @item aT
    allow transparency
    @end table
@item Other
    @table @kbd
    @item av
    eVert normals: always face viewer
    @item #aw
    Line Width (pixels)
    @item #ac
    edges Closer than faces (try 5-100)
    @end table
@item Color
    @table @kbd
    @item Cf
    faces
    @item Ce
    edges
    @item Cn
    normals
    @item Cb
    bounding boxes
    @item CB
    background
    @end table
@item Motions
    @table @kbd
    @item r
    rotate
    @item t
    translate
    @item z
    zoom FOV
    @item f
    fly
    @item o
    orbit
    @item s
    scale
    @item w
    recenter target
    @item W
    recenter all
    @item h
    halt
    @item H
    halt all
    @item @@
    select center of motion (e.g. @kbd{g 3 @@})
    @item L
    Look At object
    @end table
@item Viewing
    @table @kbd
    @item 0vp
    Orthographic view
    @item 1vp
    Perspective view
    @item  vd
    Draw other views' cameras
    @item #vv
    field of View
    @item #vn
    near clip distance
    @item #vf
    far clip distance
    @item  v+
    add new camera
    @item  vx
    cursor on/off
    @item  vb
    backfacing poly cull on/off
    @item #vl
    focal length
    @item  v~
    Software shading on/off
    @end table
@item Panels
    @table @kbd
    @item Pm
    Main
    @item Pa
    Appearance
    @item Pl
    Lighting
    @item Po
    Obscure
    @item Pt
    Tools
    @item Pc
    Cameras
    @item PC
    Commands
    @item Pf
    Files
    @item Ps
    Save
    @item P-
    read commands from tty
    @end table
@item Lights
    @table @kbd
    @item ls
    show lights
    @item le
    edit lights
    @end table
@item Space
    @table @kbd
    @item me
    Euclidean
    @item mh
    Hyperbolic
    @item ms
    Spherical
    @end table
@item Model
    @table @kbd
    @item mv
    Virtual
    @item mp
    Projective
    @item mc
    Conformal
    @end table
@item Other
    @table @kbd
    @item 0N
    normalizaton: none
    @item 1N
    normalization: each
    @item 2N all
    normalization: all
    @item ui
    motion: Inertia
    @item uc
    motion: Constrain to axis
    @item uo
    motion: object's Own coordinates
    @item <
    @item Pf
    load geometry/command file
    @item dd
    delete target object
    @item >
    @item Ps
    save state to file
    @item TV
    NTSC mode toggle
    @item p
    pick as target object (e.g. @kbd{g 3 p})
    With no prefix, selects the object under the
    mouse cursor (like double-clicking the right mouse)
    @end table
@end table

@comment ****************************************************************
@node OOGL File Formats,Conventions,Keyboard Shortcuts,Top
@chapter OOGL File Formats

The objects that you can load into Geomview are called OOGL objects.
OOGL stands for ``Object Oriented Graphics Library''; it is the library
upon which Geomview is built.

There are many different kinds of OOGL objects.  This chapter gives
syntactic descriptions of file formats for OOGL objects.

Examples of most file types live in Geomview's @file{data/geom}
directory.

@menu
* Conventions::                   Conventions.
* Object File Formats::           Object File Formats.
* Non-geometric objects::         Non-geometric objects.
@end menu

@comment ================================================================
@node Conventions,Common syntax,OOGL File Formats,OOGL File Formats
@section Conventions

@menu
* Common syntax::                  Syntax Common to All OOGL File Formats.
* File names::                     File Names.
* Vertices::                       Vertices.
* Surface normal directions::      Surface normal directions.
* Transformation matrices::        Transformation matrices.
* Binary format::                  Binary format.
* References::                     Embedded objects and external-object references.
* Appearances::                    Appearances.
@end menu

@comment ----------------------------------------------------------------
@node Common syntax,File names,Conventions,Conventions
@subsection Syntax Common to All OOGL File Formats

Most OOGL object file formats are free-format ASCII --- any amount of
white space (blanks, tabs, newlines) may appear between tokens (numbers,
key words, etc.).  Line breaks are almost always insignificant, with a
couple of exceptions as noted.  Comments begin with # and continue to
the end of the line; they're allowed anywhere a newline is.

Binary formats are also defined for several objects; @xref{Binary
format}, and the individual object descriptions.

Typical OOGL objects begin with a key word designating object type,
possibly with modifiers indicating presence of color information etc.
In some formats the key word is optional, for compatibility with file
formats defined elsewhere.  Object type is then determined by
guessing from the file suffix (if any) or from the data itself.

Key words are case sensitive.  Some have optional prefix letters
indicating presence of color or other data; in this case the order of
prefixes is significant, e.g. @code{CNMESH} is meaningful but
@code{NCMESH} is invalid.

@comment ----------------------------------------------------------------
@node File names,Vertices,Common syntax,Conventions
@subsection File Names

When OOGL objects are read from disk files, the OOGL library uses the
file suffix to guess at the file type.

If the suffix is unrecognized, or if no suffix is available (e.g. for an
object being read from a pipe, or embedded in another OOGL object), all
known types of objects are tried in turn until one accepts the data as
valid.

@comment ----------------------------------------------------------------
@node Vertices,Surface normal directions,File names,Conventions
@subsection Vertices

Several objects share a common style of representing vertices with
optional per-vertex surface-normal and color.  All vertices within an
object have the same format, specified by the header key word.

All data for a vertex is grouped together (as opposed to e.g. giving
coordinates for all vertices, then colors for all vertices, and so on).

The syntax is

@table @samp
@item @var{x}  @var{y}  @var{z}
(3-D floating-point vertex coordinates) or
@item @var{x}  @var{y}  @var{z}  @var{w}
(4-D floating-point vertex coordinates)
@end table

optionally followed by

@table @samp
@item @var{nx}  @var{ny}  @var{nz}
(normalized 3-D surface-normal if present)
@end table

optionally followed by

@table @samp
@item @var{r}  @var{g}  @var{b}  @var{a}
(4-component floating-point color if present, each component in range
0..1.  The @var{a} (alpha) component represents opacity: 0 transparent, 1
opaque.)
@end table

Values are separated by white space, and line breaks
are immaterial.

@comment ----------------------------------------------------------------
@node Surface normal directions,Transformation matrices,Vertices,Conventions
@subsection Surface normal directions

Geomview uses normal vectors to determine how an object is shaded.
The direction of the normal is significant in this calculation.

When normals are supplied with an object, the direction of the normal
is determined by the data given.

When normals are not supplied with the object, Geomview computes normal
vectors automatically; in this case normals point toward the side from
which the vertices appear in counterclockwise order.

On parametric surfaces (Bezier patches), the normal at point P(u,v)
is in the direction dP/du cross dP/dv.

@comment ----------------------------------------------------------------
@node Transformation matrices,Binary format,Surface normal directions,Conventions
@subsection Transformation matrices

Some objects incorporate 4x4 real matrices for homogeneous object
transformations.  These matrices act by multiplication on the right of
vectors.  Thus, if p is a 4-element row vector representing homogeneous
coordinates of a point in the OOGL object, and A is the 4x4 matrix, then
the transformed point is p' = p A.  This matrix convention is common in
computer graphics; it's the transpose of that often used in mathematics,
where points are column vectors multiplied on the right of matrices.


Thus for Euclidean transformations, the translation components appear in
the fourth row (last four elements) of A.  A's last column (4th, 8th,
12th and 16th elements) are typically 0, 0, 0, and 1 respectively.

@comment ----------------------------------------------------------------
@node Binary format,References,Transformation matrices,Conventions
@subsection Binary format

Many OOGL objects accept binary as well as ASCII file formats.
These files begin with the usual ASCII token (e.g. @code{CQUAD})
followed by the word @code{BINARY}.
Binary data begins at the byte following the first newline after
@code{BINARY}.  White space and a single comment may intervene, e.g.

@example
OFF BINARY	# binary-format "OFF" data follows 
@end example

Binary data comprise 32-bit integers and 32-bit IEEE-format floats, both
in big-endian format (i.e., with most significant byte first).  This is
the native format for 'int's and 'float's on Sun-3's, Sun-4's, and
Irises, among others.

Binary data formats resemble the corresponding ASCII formats, with ints
and floats in just the places you'd expect.  There are some exceptions
though, specifically in the @code{QUAD} and @code{OFF} file formats.
Details are given in the individual file format descriptions.
@xref{QUAD}, and @xref{OFF}.

Binary OOGL objects may be freely mixed in ASCII object streams:

@example
LIST
@{ = MESH BINARY
@dots{} binary data for mesh here @dots{}
@}
@{ = QUAD
	1 0 0   0 0 1   0 1 0  0 1 0
@}
@end example

Note that ASCII data resumes immediately following the last byte of
binary data.

Naturally, it's impossible to embed comments inside a binary-format OOGL
object, though comments may appear in the header before the beginning of
binary data.

@comment ----------------------------------------------------------------
@node References,Appearances,Binary format,Conventions
@subsection Embedded objects and external-object references

Some object types (@code{LIST}, @code{INST}) allow references to other
OOGL objects, which may appear literally in the data stream, be loaded
from named disk files, or be communicated from elsewhere via named
objects.  Gcl commands also accept geometry in these forms.

The general syntax is

@example
 <oogl-object>  ::=
	[ "@{" ]
	    [ "define" @code{symbolname} ]
	    [ "appearance" @code{appearance} ]
	    [ ["="] @code{object-keyword} @dots{}
		 | "<" @code{filename}
		 | ":" @code{symbolname} ]
	[ "@}" ]
@end example

where "quoted" items are literal strings (which appear without the
quotes), [bracketed] items are optional, and | denotes alternatives.
Curly braces, when present, must match; the outermost set of curly
braces is generally required when the object is in a larger context,
e.g. when it is part of a larger object or embedded in a Geomview
command stream.

For example, each of the following three lines:
@example
	@{ define fred   QUAD 1 0 0  0 0 1  0 1 0  1 0 0 @}

	@{ appearance @{ +edge @} LIST @{ < "file1" @} @{ : fred @} @}

	VECT 1 2 0   2 0   0 0 0   1 1 2
@end example
@noindent
is a valid OOGL object.  The last example is only valid when it is
delimited unambiguously by residing in its own disk file.

The "<" construct causes a disk file to be read.  Note that this isn't a
general textual "include" mechanism; a complete OOGL object must appear
in the referenced file.

Files read using "<" are sought first in the directory of the file which
referred to them, if any; failing that, the normal search path (set by
Geomview's @code{load-path} command) is used.  The default search looks
first in the current directory, then in the Geomview data directories.

The ":" construct allows references to symbols, created with
@code{define}.  A symbol's initial value is a null object.  When a
symbol is (re)defined, all references to it are automatically changed;
this is a crucial part of the support for interprocess communication.
Some future version of the documentation should explain this better@dots{}

Again, white space and line breaks are insignificant, and "#" comments
may appear anywhere.


@comment ----------------------------------------------------------------
@node Appearances,Object File Formats,References,Conventions
@subsection Appearances

Geometric objects can have associated "appearance" information,
specifying shading, lighting, color, wireframe vs. shaded-surface
display, and so on.  Appearances are inherited through object
hierarchies, e.g. attaching an appearance to a @code{LIST} means that the
appearance is applied to all the @code{LIST}'s members.

Some appearance-related properties are relegated to "material" and
"lighting" substructures.  Take care to note which properties belong to
which structure.

Here's an example appearance structure including values for all
attributes.  Order of attributes is unimportant.  As usual, white space
is irrelevant.  Boolean attributes may be preceded by "+" or "-" to turn
them on or off; "+" is assumed if only the attribute name appears.
Other attributes expect values.

A "*" prefix on any attribute, e.g. "*+edge" or "*linewidth 2",
selects "override" status for that attribute.

@example
appearance @{
  +face               # draw faces of polygons
  -edge               # don't draw edges of polygons
  -transparent        # don't attempt transparency (not implemented)
  +normal             # do draw surface-normal vectors
  normscale .25       # @dots{} with length .25 in object coordinates

  +evert              # do evert polygon normals where needed so as
                      #   to always face the camera

  shading smooth      # or ``shading constant'' or ``shading flat''.
                      # smooth = Gouraud shading; flat = faceted.

  linewidth 3         # lines & edges are 3 pixels wide.

  material @{         # Here's a material definition;
                      # it could also be read from a file as in
                      #  ``material < file.mat''

      ka  1.0         # ambient reflection coefficient.
      ambient .3 .5 .3 # ambient color (red, green, blue components)
                      # The ambient contribution to the shading is
                      # the product of ka, the ambient color,
                      # and the color of the ambient light.

      kd  0.8         # diffuse-reflection coefficient.
      diffuse .9 1 .4 # diffuse color.
                        # (In ``shading constant'' mode, the surface
                        # is colored with the diffuse color.)

      ks 1.0          # specular reflection coefficient.
      specular 1 1 1  # specular (highlight) color.
      shininess  25   # specular exponent; larger values give
                      # sharper highlights.

      alpha   1.0     # opacity; 0 = transparent (invisible)
                      # when transparency is enabled.

      edgecolor   1 1 0  # line & edge color

      normalcolor 0 0 0  # color for surface-normal vectors
  @}

  lighting @{         # Lighting model

      ambient  .3 .3 .3  # ambient light

      replacelights   # ``Use only the following lights to
                      # illuminate the objects under this
                      # appearance.''
                      # Without "replacelights", any lights
                      # are added to those already in the scene.

                      # Now a collection of real lights
      light @{ 
          color  1 .7 .6      # light color
          position  1 0 .5 0  # light position [distant light]
                              # given in homogeneous coordinates.
                              # With fourth component = 0,
                              # this means a light coming from
                              # direction (1,0,.5).
      @}

      light @{                        # Another light.
          color 1 1 1
          position  0 0 .5 1  # light at finite position @dots{}
          location camera     # specified in camera coordinates.
                              # (Since the camera looks toward -Z,
                              # this example places the light
                              # .5 unit behind the eye.)
          # Possible "location" keywords:
          #  global    light position is in world coordinates
          #             This is the default if no location specified.
          #  camera   position is in the camera's coordinate system
          #  local    position is in the coordinate system where
          #                   the appearance was defined
      @}
  @}                   # end lighting model
@}                     # end appearance
@end example


There are rules for inheritance of appearance attributes when several
are imposed at different levels in the hierarchy.

For example, Geomview installs a backstop appearance which provides
default values for most parameters; its control panels install other
appearances which supply new values for a few attributes; user-supplied
geometry may also contain appearances.

The general rule is that the child's appearance (the one closest to the
geometric primitives) wins.  So setting an appearance attribute in an
object's definition will prevent the viewer controls from affecting that
object's display.

@comment ================================================================
@node Object File Formats,QUAD,Appearances,OOGL File Formats
@section Object File Formats

@menu
* QUAD::		List of quadrilaterals.
* MESH::		Rectangularly-connected mesh.
* BBP and BEZ::		List of Bezier surface patches.
* OFF::			Polyhedra: polygons with shared vertices.
* VECT::		List of points and lines.
* INST::		Transformed Instance of another object.
* LIST::		List of other objects.
* TLIST::		Collection of 4x4 transformation matrices.
* GROUP::		Obsolete format for collections of objects.
* DISCGRP::             Discrete Group objects.
@end menu


@comment ----------------------------------------------------------------
@node QUAD,MESH,Object File Formats,Object File Formats
@subsection @code{QUAD}: collection of quadrilaterals

The conventional suffix for a @code{QUAD} file is @file{.quad}.

The file syntax is

@example
   [C][N][4]QUAD  -or-  [C][N][4]POLY		   # Key word
   @var{vertex}  @var{vertex}  @var{vertex}  @var{vertex}  # 4*N vertices for some N
   @var{vertex}  @var{vertex}  @var{vertex}  @var{vertex}
   @dots{}
@end example

The leading key word is @code{[C][N][4]QUAD} or @code{[C][N][4]POLY},
where the optional @code{C} and @code{N} prefixes indicate that each vertex
includes colors and normals respectively.  That is, these files
begin with one of the words

@code{QUAD} @code{CQUAD} @code{NQUAD} @code{CNQUAD} @code{POLY}
@code{CPOLY} @code{NPOLY} @code{CNPOLY}

(but not @code{NCQUAD} or @code{NCPOLY}).  @code{QUAD} and @code{POLY}
are synonymous; both forms are allowed just for compatibility with
ChapReyes.

Following the key word is an arbitrary number of groups of four
vertices, each group describing a quadrilateral.  See the Vertex syntax
above.  The object ends at end-of-file, or with a closebrace if
incorporated into an object reference (see above).

A @code{QUAD BINARY} file format is accepted; @xref{Binary format}.  The
first word of binary data must be a 32-bit integer giving the number of
quads in the object; following that is a series of 32-bit floats,
arranged just as in the ASCII format.

@comment ----------------------------------------------------------------
@node MESH,BBP and BEZ,QUAD,Object File Formats
@subsection @code{MESH}: rectangularly-connected mesh

The conventional suffix for a @code{MESH} file is @file{.mesh}.

The file syntax is

@example
[C][N][Z][4][U][u][v]MESH    # Key word
@var{Nu} @var{Nv}            # Mesh dimensions
                             # @var{Nu}*@var{Nv} vertices, in format specified
                             # by initial key word
@var{vertex}(u=0,v=0)  @var{vertex}(1,0)  @dots{} @var{vertex}(@var{Nu}-1,0)
@var{vertex}(0,1) @dots{}    @var{vertex}(@var{Nu}-1,1)
@dots{}
@var{vertex}(0,@var{Nv}-1) @dots{} @var{vertex}(@var{Nu}-1,@var{Nv}-1)
@end example

The key word is  @code{[C][N][Z][4][U][u][v]MESH}.
The optional prefix characters mean:

@table @samp
@item C
Each vertex (see Vertices above) includes a 4-component color.
@item N
Each vertex includes a surface normal vector.
@item Z
Of the 3 vertex position values, only the Z component is present; X and
Y are omitted, and assumed to equal the mesh (u,v) coordinate so X
ranges from 0 .. (Nu-1), Y from 0 .. (Nv-1) where Nu and Nv are the mesh
dimensions -- see below.
@item 4
Vertices are 4D, each consists of 4 floating values.  @code{Z} and
@code{4} cannot both be present.
@item U
Each vertex includes a 3-component texture space parameter.  This is
not yet implemented and should not be used.
@item u
The mesh is wrapped in the u-direction, so the 
(0,v)'th vertex is connected to the (@var{Nu}-1,v)'th for all v.
@item v
The mesh is wrapped in the v-direction, so the (u,0)'th vertex is
connected to the (u,@var{Nv}-1)'th for all u.  Thus a u-wrapped or
v-wrapped mesh is topologically a cylinder, while a uv-wrapped mesh is a
torus.
@end table

Note that the order of prefix characters is significant; a colored,
u-wrapped mesh is a @code{CuMESH} not a @code{uCMESH}.

Following the mesh header are integers @var{Nu} and @var{Nv},
the dimensions of the mesh.

Then follow @var{Nu}*@var{Nv} vertices, each in the form given by the header.
They appear in v-major order, i.e. if we name each vertex by (u,v)
then the vertices appear in the order

@example
(0,0) (1,0) (2,0) (3,0) @dots{}  (@var{Nu}-1,0)
(0,1) (1,1) (2,1) (3,1) @dots{}  (@var{Nu}-1,1)
@dots{}
(0,Nv-1)		@dots{}  (@var{Nu}-1,@var{Nv}-1)
@end example

A @code{MESH BINARY} format is accepted; @xref{Binary format}.  The
values of @var{Nu} and @var{Nv} are 32-bit integers; all other values
are 32-bit floats.

@comment ----------------------------------------------------------------
@node BBP and BEZ,OFF,MESH,Object File Formats
@subsection Bezier Surfaces

The conventional file suffixes for Bezier surface files are @file{.bbp}
or @file{.bez}.  A file with either suffix may contain either type of
patch.

Syntax:

@example
  [ST]BBP -or- [C]BEZ<@var{Nu}><@var{Nv}><@var{Nd}>[_ST]
			# @var{Nu}, @var{Nv} are u- and v-direction 
			# polynomial degrees in range 1..6
			# @var{Nd} = dimension: 3->3-D, 4->4-D (rational)
			# (The '<' and '>' do not appear in the input.)
			# @var{Nu},@var{Nv},@var{Nd} are each a single decimal digit.
			# BBP form implies @var{Nu}=@var{Nv}=@var{Nd}=3 so BBP = BEZ333.

		# Any number of patches follow the header
			# (@var{Nu}+1)*(@var{Nv}+1) patch control points
			# each 3 or 4 floats according to header
  @var{vertex}(u=0,v=0)  @var{vertex}(1,0) @dots{} @var{vertex}(@var{Nu},0)
  @var{vertex}(0,1)			   @dots{} @var{vertex}(@var{Nu},1)
  @dots{}
  @var{vertex}(0,@var{Nv})		   @dots{} @var{vertex}(@var{Nu},@var{Nv})

			# ST texture coordinates if mentioned in header
  @code{S}(u=0,v=0)	@code{T}(0,0)	@code{S}(0,@var{Nv}) @code{T}(0,@var{Nv})
  @code{S}(@var{Nu},0)	@code{T}(@var{Nu},0)	@code{S}(@var{Nu},@var{Nv}) @code{T}(@var{Nu},@var{Nv})

			# 4-component float (0..1) R G B A colors
			# for each patch corner if mentioned in header
  @code{RGBA}(0,0)   @code{RGBA}(0,@var{Nv})
  @code{RGBA}(@var{Nu},0)  @code{RGBA}(@var{Nu},@var{Nv})
@end example

These formats represent collections of Bezier surface patches, of
degrees up to 6, and with 3-D or 4-D (rational) vertices.

The header keyword has the forms @code{[ST]BBP} or
@code{[C]BEZ<@var{Nu}><@var{Nv}><@var{Nd}>[_ST]} (the '<' and '>' are
not part of the keyword.

The @code{ST} prefix on @code{BBP}, or @code{_ST} suffix on
@code{BEZuvn}, indicates that each patch includes four pairs of
floating-point texture-space coordinates, one for each corner of the
patch.

The @code{C} prefix on @code{BEZuvn} indicates a colored patch,
including four sets of four-component floating-point colors (red, green,
blue, and alpha) in the range 0..1, one color for each corner.

@var{Nu} and @var{Nv}, each a single digit in the range 1..6, are the
patch's polynomial degree in the u and v direction respectively. 

@var{Nd} is the number of components in each patch vertex, and must be
either @code{3} for 3-D or @code{4} for homogeneous coordinates, that
is, rational patches.

@code{BBP} patches are bicubic patches with 3-D vertices, so @code{BBP}
= @code{BEZ333} and @code{STBBP} = @code{BEZ333_ST}.

Any number of patches follow the header.  Each patch comprises a series
of patch vertices, followed by optional (s,t) texture coordinates,
followed by optional (r,g,b,a) colors.

Each patch has (@var{Nu}+1)*(@var{Nv}+1) vertices in v-major order, so that if we
designate a vertex by its control point indices (u,v) the order is
@example
     (0,0) (1,0) (2,0) @dots{}  (@var{Nu},0)
     (0,1) (1,1) (2,1) @dots{}  (@var{Nu},1)
     @dots{}
     (0,@var{Nv})            @dots{}  (@var{Nu},@var{Nv})
@end example
@noindent
with each vertex containing either 3 or 4 floating-point numbers
as specified by the header.
   
If the header calls for ST coordinates, four pairs of floating-point
numbers follow: the texture-space coordinates for the (0,0),
(@var{Nu},0), (0,@var{Nv}), and (@var{Nu},@var{Nv}) corners of the
patch, respectively.

If the header calls for colors, four four-component (red, green, blue,
alpha) floating-point colors follow, one for each patch corner.

The series of patches ends at end-of-file, or with a closebrace if
incorporated in an object reference.

@comment ----------------------------------------------------------------
@node OFF,VECT,BBP and BEZ,Object File Formats
@subsection OFF Files

The conventional suffix for @code{OFF} files is @file{.off}.

Syntax:

@example
[C][N][4]OFF		# Header keyword (optional)
@var{NVertices}  @var{NFaces}  @var{NEdges}   # NEdges not used or checked

@var{x}[0]  @var{y}[0]  @var{z}[0]	# Vertices, possibly with colors
    			# and/or normals if @code{COFF} or @code{NOFF}
@dots{}
@var{x}[@var{NVertices}-1]  @var{y}[@var{NVertices}-1]  @var{z}[@var{NVertices}-1]

    			# Faces
    			# @var{Nv} = # vertices on this face
    			# @var{v}[0] @dots{} @var{v}[@var{Nv}-1]: vertex indices
    			#		in range 0..@var{NVertices}-1
@var{Nv}  @var{v}[0] @var{v}[1] @dots{} @var{v}[@var{Nv}-1]  @var{colorspec}
@dots{}
    			# @var{colorspec} continues past @var{v}[@var{Nv}-1]
    			# to end-of-line; may be 0 to 4 numbers
    			# nothing: default
    			#  integer: colormap index
    			# 3 or 4 integers: RGB[A] values 0..255
				# 3 or 4 floats: RGB[A] values 0..1
@end example

@code{OFF} files (name for "object file format") represent collections
of planar polygons with possibly shared vertices, a convenient way to
describe polyhedra.  The polygons may be concave but there's no
provision for polygons containing holes.

An @code{OFF} file may begin with the keyword @code{OFF}; it's



recommended but optional, as many existing files lack this keyword.

Three ASCII integers follow: @var{NVertices}, @var{NFaces}, and
@var{NEdges}.  Thse are the number of vertices, faces, and edges,
respectively.  Current software does not use nor check @var{NEdges}; it
needn't be correct but must be present.

The vertex coordinates follow: dimension * @var{Nvertices}
floating-point values.  They're implicitly numbered 0 through
@var{NVertices}-1.  dimension is either 3 (default) or 4 (specified by
the key character @code{4} directly before @code{OFF} in the keyword).

Following these are the face descriptions, typically written
with one line per face.  Each has the form
@example
@var{N}  @var{Vert1} @var{Vert2} @dots{} @var{VertN}  [@var{color}]
@end example
@noindent
Here @var{N} is the number of vertices on this face,
and @var{Vert1} through @var{VertN} are indices into the list of
vertices (in the range 0..@var{NVertices}-1).

The optional @var{color} may take several forms.  Line breaks are
significant here: the @var{color} description begins after @var{VertN}
and ends with the end of the line (or the next # comment).  A
@var{color} may be:

@table @asis
@item nothing
the default color
@item one integer
index into "the" colormap; see below
@item three or four integers
RGB and possibly alpha values in the range 0..255
@item three or four floating-point numbers
RGB and possibly alpha values in the range 0..1
@end table

For the one-integer case, the colormap is currently read from the file
@file{cmap.fmap} in Geomview's @file{data} directory.  Some better
mechanism for supplying a colormap is likely someday.

The meaning of "default color" varies.  If no face of the object has a
color, all inherit the environment's default material color.  If some
but not all faces have colors, the default is gray (R,G,B,A=.666).

A @code{[C][N]OFF BINARY} format is accepted; @xref{Binary format}.  It
resembles the ASCII format in almost the way you'd expect, with 32-bit
integers for all counters and vertex indices and 32-bit floats for
vertex positions (and vertex colors or normals if
@code{COFF}/@code{NOFF}/@code{CNOFF} format).

Exception: each face's vertex indices are followed by an integer
indicating how many color components accompany it.  Face color
components must be floats, not integer values.  Thus a colorless
triangular face might be represented as

@example
int int int int int
3   17   5   9   0
@end example

while the same face colored red might be

@example
int int int int int float float float float
 3  17   5   9   4   1.0   0.0   0.0   1.0
@end example


@comment ----------------------------------------------------------------
@node VECT,INST,OFF,Object File Formats
@subsection VECT Files

The conventional suffix for @code{VECT} files is @file {.vect}.

Syntax:

@example
[4]VECT
@var{NPolylines}  @var{NVertices}  @var{NColors}

@var{Nv[0]} @dots{} @var{Nv[NPolylines-1]}     # number of vertices
                                           # in each polyline

@var{Nc[0]} @dots{} @var{Nc[NPolylines-1]}     # number of colors supplied
                                           # in each polyline

@var{Vert[0]} @dots{} @var{Vert[NVertices-1]}  # All the vertices
                                           # (3*NVertices floats)

@var{Color[0]} @dots{} @var{Color[NColors-1]}  # All the colors
                                           # (4*NColors floats, RGBA)
@end example

@code{VECT} objects represent lists of polylines (strings of connected
line segments, possibly closed).  A degenerate polyline can be used to
represent a point.

A @code{VECT} file begins with the key word @code{VECT} or @code{4VECT}
and three integers: @var{NLines}, @var{NVertices}, and @var{NColors}.
Here @var{NLines} is the number of polylines in the file,
@var{NVertices} the total number of vertices, and @var{NColors} the
number of colors as explained below.

Next come @var{NLines} integers

@center @var{Nv[0]} @var{Nv[1]} @var{Nv[2]} @dots{} @var{Nv[NLines-1]}

giving the number of vertices in each polyline.  A negative number
indicates a closed polyline; 1 denotes a single-pixel point.  The sum
(of absolute values) of the @var{Nv[i]} must equal @var{NVertices}.

Next come @var{NLines} more integers Nc[i]: the number of colors in
each polyline.  Normally one of three values:

@table @asis
@item 0
No color is specified for this polyline.  It's drawn in the same color
as the previous polyline.
@item 1
A single color is specified.  The entire polyline is drawn in that
color.
@item abs(@var{Nv[i]})
Each vertex has a color.  Either each segment is drawn in the
corresponding color, or the colors are smoothly interpolated along the
line segments, depending on the implementation.
@end table

The sum of the @var{Nc[i]} must equal @var{NColors}.

Next come @var{NVertices} groups of 3 or 4 floating-point numbers: the
coordinates of all the vertices.  If the keyword is @var{4VECT} then
there are 4 values per vertex.  The first abs(@var{Nv[0]}) of them form
the first polyline, the next abs(@var{Nv[1]}) form the second and so on.

Finally @var{NColors} groups of 4 floating-point numbers give red,
green, blue and alpha (opacity) values.  The first @var{Nc[0]} of them
apply to the first polyline, and so on.

A @var{VECT BINARY} format is accepted; @xref{Binary format}.  The
binary format exactly follows the ASCII format, with 32-bit ints where
integers appear, and 32-bit floats where real values appear.



@comment ----------------------------------------------------------------
@node INST,INST Examples,VECT,Object File Formats
@subsection INST Files

The conventional suffix for a @code{INST} file is @file{.inst}.

An @code{INST} applies a 4x4 transformation to another OOGL object.  It
begins with @code{INST} followed by these sections which may appear in
any order:
@example
geom @var{oogl-object}
@end example
@noindent
specifies the OOGL object to be instantiated.  @xref{References}, for
the syntax of an @var{oogl-object}.  The keyword @code{unit} is a
synonym for @code{geom}.
@example
transform   ["@{"] @code{4x4 transform} ["@}"]
@end example
@noindent
specifies a single transformation matrix.  Either the
matrix may appear literally as 16 numbers, or there may be
a reference to a "transform" object, i.e.
@example
"<" file-containing-4x4-matrix
@end example
@noindent
or
@example
":" symbol-representing-"transform"-object>
@end example

Another way to specify the transformation is

@example
transforms
    @var{oogl-object}
@end example

The @var{oogl-object} must be a @code{TLIST} object (list of
transformations) object, or a @code{LIST} whose members are ultimately
@code{TLIST} objects.  In effect, the @code{transforms} keyword takes a
collection of 4x4 matrices and replicates the @code{geom} object, making
one copy for each 4x4 matrix.

If no @code{transform} nor @code{transforms} keyword appears, no
transformation is applied (actually the identity is applied).  This
might be useful, e.g., for wrapping an appearance around an
externally-supplied object.

@xref{Transformation matrices}, for the matrix format.

There is no INST BINARY format.

@menu
* INST Examples::	Some example of @code{INST} Files.
@end menu

@comment ................................................................
@node INST Examples,LIST,INST,Object File Formats
@subsubsection INST Examples

Here are some examples of @code{INST} files

@example
INST
     unit < xyz.vect
     transform @{
        1 0 0 0
        0 1 0 0
        0 0 1 0
        1 3 0 1
     @}
@end example

@example
@{ appearance @{ +edge  material @{ edgecolor 1 1 0 @} @}
    INST geom < mysurface.quad @}
@end example

@example
@{INST transform @{: T@} geom @{<dodec.off@}@}
@end example

@example
@{ INST
     transforms
         @{ LIST
     	@{ < some-matrices.prj @}
     	@{ < others.prj @}
     	@{ TLIST <still more of them> @}
     	
         @}
     geom
         @{ # stuff replicated by all the above matrices
     	@dots{}
         @}
@}
@end example

@comment ----------------------------------------------------------------
@node LIST,TLIST,INST Examples,Object File Formats
@subsection LIST Files

The conventional suffix for a @code{LIST} file is @file{.list}.

A list of OOGL objects

Syntax:

@example
LIST
    @var{oogl-object}
    @var{oogl-object}
    @dots{}
@end example

Note that there's no explicit separation between the oogl-objects, so
they should be enclosed in curly braces (@{ @}) for sanity.  Likewise
there's no explicit marker for the end of the list; unless appearing
alone in a disk file, the whole construct should also be wrapped in
braces, as in:

@example
   @{ LIST @{ QUAD @dots{} @} @{ < xyz.quad @} @}
@end example

A @code{LIST} with no elements, i.e. @code{@{ LIST @}}, is valid, and is
the easiest way to create an empty object.  For example, to remove a
symbol's definition you might write

@example
   @{ define somesymbol  @{ LIST @} @}
@end example


@comment ----------------------------------------------------------------
@node TLIST,GROUP,LIST,Object File Formats
@subsection TLIST Files


The conventional suffix for a @code{TLIST} file is @file{.grp} ("group")
or or @file{.prj} ("projective" matrices).

Collection of 4x4 matrices, used in the @code{transforms} section of and
@code{INST} object.

Syntax:

@example
TLIST			# key word

<4x4 matrix (16 floats)>
@dots{}				# Any number of 4x4 matrices
@end example

@code{TLIST}s are used only within the @code{transforms} clause of an
@code{INST} object.  They cause the @code{INST}s @code{geom} object to
be instantiated once under each of the transforms in the @code{TLIST}.
The effect is like that of a @code{LIST} of @code{INST}s each with a
single transform, and all referring to the same object, but is more
efficient.

Be aware that a @code{TLIST} is a kind of geometry object, distinct from a 
@code{transform} object.  Some contexts expect one type of object,
some the other.  For example in
@example
INST transform @{ : @var{myT} @} geom @{ @dots{} @}
@end example
@noindent
@var{myT} must be a transform object, which might have been
created with the gcl
@example
(read transform @{ define myT 1 0 0 1 @dots{} @})
@end example
@noindent
while in
@example
    INST transforms @{ : @var{myTs} @} geom @{ @dots{} @}
or  INST transforms @{ LIST @{: @var{myTs}@} @{< more.prj@} @} geom @{ @dots{} @}
@end example
@noindent
@var{myTs} must be a geometry object, defined e.g. with
@example
    (read geometry @{ define @var{myTs} @{ TLIST 1 0 0 1 @dots{} @} @})
@end example

A @code{TLIST BINARY} format is accepted.  Binary data begins with a
32-bit integer giving the number of transformations, followed by that
number of 4x4 matrices in 32-bit floating-point format.  The order of
matrix elements is the same as in the ASCII format.


@comment ----------------------------------------------------------------
@node GROUP,DISCGRP,TLIST,Object File Formats
@subsection GROUP Files

This format is obsolete, but is still accepted.  It combined the
functions of @code{INST} and @code{TLIST}, taking a series of
transformations and a single Geom (@code{unit}) object, and replicating
the object under each transformation.

@example
GROUP @dots{} < matrices > @dots{} unit @{ @var{oogl-object} @}
@end example

is still accepted and effectively translated into

@example
INST
	transforms @{ TLIST @dots{} <matrices> @dots{} @}
	unit @{ @var{oogl-object} @}
@end example

@comment ----------------------------------------------------------------
@node DISCGRP,Non-geometric objects,GROUP,Object File Formats
@subsection DISCGRP Files

This format is for discrete groups, such as appear in the theory of
manifolds or in symmetry patterns.  This format has its own man page.
See discgrp(5).

@comment ================================================================
@node Non-geometric objects,transform,DISCGRP,OOGL File Formats
@section Non-geometric objects


The syntax of these objects is given in the form used in
@xref{References}, where "quoted" items should appear literally but
without quotes, square bracketed ([ ]) items are optional, and | separates
alternative choices.

@menu
* transform::	Transformation matrices.
* camera::	Cameras.
* window::	Windows.
@end menu

@comment ----------------------------------------------------------------
@node transform,camera,Non-geometric objects,Non-geometric objects
@subsection Transform Objects

Where a single 4x4 matrix is expected -- as in the
@code{INST} @code{transform} field, the camera's @code{camtoworld} transform
and the Geomview @code{xform*} commands -- use a transform object.

Note that a transform is distinct from a @code{TLIST}, which is a type
of geometry.  @code{TLIST}s can contain one or more 4x4 transformations;
"transform" objects must have exactly one.

Why have both?  In many places -- e.g. camera positioning -- it's only
meaningful to have a single transform.  Using a separate object type
enforces this.

Syntax for a transform object is

@example
<transform> ::= 
  [ "@{" ]             (curly brace, generally needed to make
                       the end of the object unambiguous.)

   [ "transform" ]    (optional keyword; unnecessary if the type
                       is determined by the context, which it
                       usually is.)
   [ "define" <name> ]
                      (defines a transform named <name>, setting
                       its value from the stuff which follows)

      <sixteen floating-point numbers>
                      (interpreted as a 4x4 homogeneous transform
		       given row by row, intended to apply to a
                       row vector multiplied on its LEFT, so that e.g.
                       Euclidean translations appear in the bottom row)
   | 
      "<" <filename>  (meaning: read transform from that file)
   |
      ":" <name>      (meaning: use variable <name>,
                        defined elsewhere; if undefined the initial
                        value is the identity transform)

 [ "@}" ]              (matching curly brace)
@end example

The whole should be enclosed in @{ braces @}.  Braces are not essential
if exactly one of the above items is present, so e.g. a 4x4 array of
floats standing alone may but needn't have braces.

Some examples, in contexts where they might be used:

@example
# Example 1: A gcl command to define a transform
# called "fred"

(read transform @{ transform  define fred
         1 0 0 0
         0 1 0 0
         0 0 1 0
        -3 0 1 1
    @}
)
@end example

@example
# Example 2:  A camera object using transform
# "fred" for camera positioning
# Given the definition above, this puts the camera at
# (-3, 0, 1), looking toward -Z.

@{ camera
        halfyfield 1
        aspect 1.33
        camtoworld @{ : fred @}
@}
@end example

@comment ----------------------------------------------------------------
@node camera,window,transform,Non-geometric objects
@subsection cameras

A camera object specifies the following properties of a camera:

@table @asis
@item position and orientation
specified by either a camera-to-world or world-to-camera transformation;
this transformation does not include the projection, so it's typically
just a combination of translation and rotation.  Specified as a
transform object, typically a 4x4 matrix.
@item "focus" distance
Intended to suggest a typical distance from the camera to the object of
interest; used for default camera positioning (the camera is placed at
(X,Y,Z) = (0,0,focus) when reset) and for adjusting field-of-view when
switching between perspective and orthographic views.
@item window aspect ratio
True aspect ratio in the sense <Xsize>/<Ysize>.  This normally should
agree with the aspect ratio of the camera's window.  Geomview normally
adjusts the aspect ratio of its cameras to match their associated
windows.
@item near and far clipping plane distances
Note that both must be strictly greater than zero.  Very large
<far>/<near> distance ratios cause Z-buffering to behave badly; part of
an object may be visible even if somewhat more distant than another.
@item field of view
Specified in either of two forms.
@table @samp
  @item fov 
is the field of view -- in degrees if perspective, or linear
distance if orthographic -- in the @emph{shorter} direction.
  @item halfyfield 
is half the projected Y-axis field, in world coordinates (not angle!),
at unit distance from the camera.  For a perspective camera, halfyfield
is related to angular field:

@center halfyfield = tan( Y_axis_angular_field / 2 )

while for an orthographic one it's simply:

@center halfyfield = Y_axis_linear_field / 2

@end table

This odd-seeming definition is (a) easy to calculate with and
(b) well-defined in both orthographic and perspective views.
@end table


The syntax for a camera is:

@example
<camera> ::=

   [ "camera" ]			(optional keyword)
    [ "@{" ]			(opening brace, generally required)
	[ "define" <name> ]

	"<" <filename>
      |
	":" <name>
      |
				(or any number of the following,
				 in any order@dots{})

	"perspective"  @{"0" | "1"@}		(default 1)
					(otherwise orthographic)

	"stereo"       @{"0" | "1"@}		(default 0)
					(otherwise mono)

	"worldtocam" <transform>	(see transform syntax above)

	"camtoworld" <transform>
				(no point in specifying both
				 camtoworld and worldtocam; one is
				 constrained to be the inverse of						 the other)

	"halfyfield" <half-linear-Y-field-at-unit-distance>
				(default tan 40/2 degrees)

	"fov"		(angular field-of-view if perspective,
			 linear field-of-view otherwise.
			 Measured in whichever direction is smaller,
			 given the aspect ratio.  When aspect ratio
			 changes -- e.g. when a window is reshaped --
			 "fov" is preserved.)

	"frameaspect" <aspect-ratio>	(X/Y) (default 1.333)

	"near"  <near-clipping-distance>	(default 0.1)
	
	"far"	<far-clipping-distance>		(default 10.0)

	"focus" <focus-distance>		(default 3.0)

	
     [ "@}" ]				(matching closebrace)
@end example


@comment ----------------------------------------------------------------
@node window,Customization,camera,Non-geometric objects
@subsection window

A window object specifies size, position, and other window-system
related information about a window in a device-independent way.

The syntax for a window object is:

@example
window ::=

	[ "window" ]			(optional keyword)
	  [ "@{" ]			(curly brace, often required)

	    			(any of the following, in any order)

		"size"  <xsize> <ysize>
				(size of the window)

		"position"  <xmin> <xmax> <ymin> <ymax>
				(position & size)


		"noborder"
				(specifies the window should
				 have no window border)

		"pixelaspect"  <aspect>
			    (specifies the true visual aspect ratio
			     of a pixel in this window in the sense
			     xsize/ysize, normally 1.0.
			     For stereo hardware which stretches the
			     display vertically by a factor of 2,
			     ``pixelaspect 0.5'' might do.
			     The value is used when computing the
			     projection of a camera associated with
			     this window.)

	  [ "@}" ]			(matching closebrace)
@end example

Window objects are used in the Geomview @code{window} and
@code{ui-panel} commands to set default properties for future windows or
to change those of an existing window.


@comment ****************************************************************
@node Customization,Modules,window,Top
@chapter Customization: @file{.geomview} files

When Geomview is started, it loads and executes commands in a
system-wide startup file named @file{.geomview}.  This file is in the
@file{data} subdirectory of the Geomview distribution directory
@file{/u/gcg/ngrap/data} on the Geometry Center's computer system) and
contains gcl commands to configure Geomview in a way
common to all users on the system.

Next, Geomview looks for the file @file{~/.geomview} (@file{~}
stands for your home directory).  You can use this to configure
your own default Geomview behavior to suit your tastes.

After reading @file{~/.geomview}, Geomview looks for a file named
@file{.geomview} in the current directory.  If such a file exists
Geomview reads it, unless it is the same as @file{~/.geomview} (which
would be the case if you are running Geomview from your home directory).
You can use the current directory's @file{.geomview} to create a Geomview
customization specific to a certain project.

You can use @file{.geomview} files to control all kinds of things about
Geomview.  They can contain any valid gcl statements.  Especially
useful is the @code{ui-panel} command which controls the initial
placement of Geomview's panels.  For an example see the system-wide
@file{.geomview} file mentioned above.  For details of gcl,
@xref{GCL}.

It is a good idea to enclose all the commands you put in a
@file{.geomview} file in a @code{progn} statement in order to cause
Geomview to execute them all at once.  Otherwise Geomview might execute
them sequentially over the first few refresh cycles after starting up.

@comment ****************************************************************
@node Modules,Interface,Customization,Top
@chapter External Modules

An external module is a program that interacts with Geomview.  A
module communicates with Geomview through gcl and can
control any apsect of Geomview that you can control through Geomview's
user interface.

In many cases an external module is a specialized program that
implements some mathematical algorithm that creates a geometric
object that changes shape as the algorithm progresses.  The module
informs Geomview of the new object shape at each step, so the object
appears to evolve with time in the Geomview window.  In this way
Geomview serves as a @emph{display engine} for the module.

An external module may be interactive.  It can respond to mouse and
keyboard events that take place in a Geomview window, thus extending
the capability of Geomview itself.

@menu
* Interface::               How External Modules Interface with Geomview.
* Example1::                Simple External Module.
* Example2::                Simple External Module with FORMS Control Panel.
* Forms::                   The FORMS Library.
* Example3::                External Module with Bi-Directional Communication.
* Module Installation::     Module Installation.
@end menu

@node Interface,Example1,Modules,Modules
@section How External Modules Interface with Geomview

External modules appear in the @widget{Modules} browser in Geomview's
@panel{Main} panel.  To run a module, click the left mouse button on
the module's entry in the browser.  While the module is running, an
additional line for that module will appear in red in the browser.
This line begins with a number in brackets, which indicates the
@emph{instace} number of the module.  (For some modules it makes sense
to have more than one instance of the module running at the same
time.)  You can kill an external module by clicking on its red
instance entry.

By default when Geomview starts, it displays all the modules that have
been installed on your system. 

For instructions on installing a module on your system so that it will
appear in the @widget{Modules} browser every time Geomview is run by
anyone on your system, @xref{Module Installation}.

When Geomview invokes an external module, it creates pipes connected
to the module's standard input and output. (Pipes are like files
except they are used for communication between programs rather than
for storing things on a disk.)  Geomview interprets anything that the
module writes to its standard output as a gcl command.
Likewise, if the exernal module requests any data from Geomview,
Geomview writes that data to the module's standard input.  Thus all a
module has to do in order to communicate with Geomview is write
commands to standard output and (optionally) receive data on standard
input.  Note that this means that the module cannot use standard input
and output for communicating with the user.  If a module needs to
communicate with the user it can do so either through a control
panel of its own or else by responding to certain events that it finds
out about from Geomview.

@node Example1,Example2,Interface,Modules
@section Example 1: Simple External Module

This section gives a very simple external module which displays an
oscillating mesh.  To try out this example, make a copy of the file
@file{example1.c} (it is distributed with Geomview in the @file{doc}
subdirectory) in your directory and compile it with the command

@example
cc -o example1 example1.c -lm
@end example

Then put the line

@example
(emodule-define "Example 1" "./example1")
@end example

@noindent
in a file called @file{.geomview} in your current directory.  Then invoke
Geomview; it is important that you compile the example program, create
the @file{.geomview} file, and invoke Geomview all in the same
directory.  You should see "Example 1" in the @widget{Modules} browser
of Geomview's @panel{Main} panel; click on this entry in the browser to
start the module.  A surface should appear in your camera window and should
begin oscillating.  You can stop the module by clicking on the red "[1]
Example 1" line in the @widget{Modules} browser.

@example
@comment #include "example1.c"
/*
 * example1.c: oscillating mesh
 *
 * This example module is distributed with the Geomview manual.
 * If you are not reading this in the manual, see the "External
 * Modules" chapter of the manual for more details.
 *
 * This module creates an oscillating mesh.
 */

#include <math.h>
#include <stdio.h>

/* F is the function that we plot
 */
float F(x,y,t)
     float x,y,t;
@{
  float r = sqrt(x*x+y*y);
  return(sin(r + t)*sqrt(r));
@}

main(argc, argv)        
     char **argv;
@{
  int xdim, ydim;
  float xmin, xmax, ymin, ymax, dx, dy, t, dt;

  xmin = ymin = -5;             /* Set x and y            */
  xmax = ymax = 5;              /*    plot ranges         */
  xdim = ydim = 24;             /* Set x and y resolution */
  dt = 0.1;                     /* Time increment is 0.1  */

  /* Geomview setup.  We begin by sending the command
   *            (geometry example @{ : foo@})
   * to Geomview.  This tells Geomview to create a geom called
   * "example" which is an instance of the handle "foo".
   */
  printf("(geometry example @{ : foo @})\n");
  fflush(stdout);

  /* Loop until killed.
   */
  for (t=0; ; t+=dt) @{
    UpdateMesh(xmin, xmax, ymin, ymax, xdim, ydim, t);
  @}
@}

/* UpdateMesh sends one mesh iteration to Geomview.  This consists of
 * a command of the form
 *    (read geometry @{ define foo
 *       MESH
 *       ...
 *    @})
 * where ... is the actual data of the mesh.  This command tells
 * Geomview to make the value of the handle "foo" be the specified
 * mesh.
 */
UpdateMesh(xmin, xmax, ymin, ymax, xdim, ydim, t)
     float xmin, xmax, ymin, ymax, t;
     int xdim, ydim;
@{
  int i,j;
  float x,y, dx,dy;

  dx = (xmax-xmin)/(xdim-1);
  dy = (ymax-ymin)/(ydim-1);

  printf("(read geometry @{ define foo \n");
  printf("MESH\n");
  printf("%1d %1d\n", xdim, ydim);
  for (j=0, y = ymin; j<ydim; ++j, y += dy) @{
    for (i=0, x = xmin; i<xdim; ++i, x += dx) @{
      printf("%f %f %f\t", x, y, F(x,y,t));
    @}
    printf("\n");
  @}
  printf("@})\n");
  fflush(stdout);
@}
@comment #end include
@end example

The module begins by defining a function @code{F(x,y,t)} that
specifies a time-varying surface.  The purpose of the module is to
animate this surface over time.

The main program begins by defining some variables that specify
the parameters with which the function is to be plotted.

The next bit of code in the main program prints the following
line to standard output

@example
(geometry example @{ : foo @})
@end example

This tells Geomview to create a geom called @code{example} which is an
instance of the handle @code{foo}.  @emph{Handles} are a part of the
OOGL file format which allow you to name a piece of geometry whose value
can be specified elsewhere (and in this case updated many times); for
more information on handles, @xref{OOGL File Formats} In this case,
@code{example} is the title by which the user will see the object in
Geomview's object browser, and @code{foo} is the internal name of the
handle that the object is a reference to.

We then do @code{fflush(stdout)} to ensure that Geomview
receives this command immediately.  In general, since pipes may be
buffered, an external module should do this whenever it wants to be
sure Geomview has actually received everything it has printed out.

The last thing in the main program is an infinite loop that cycles
through calls to the procedure @code{UpdateMesh} with increasing
values of @code{t}.  @code{UpdateMesh} sends Geomview a command
of the form

@example
(read geometry @{ define foo 
MESH
24 24
@dots{}
@})
@end example

@noindent
where @code{@dots{}} is a long list of numbers.  This command tells Geomview
to make the value of the handle @code{foo} be the specified mesh.  As
soon as Geomview receives this command, the geom being displayed
changes to reflect the new geometry.

The mesh is given in the format of an OOGL MESH.  This begins with
the keyword @code{MESH}.  Next come two numbers that give the x and y
dimensions of the mesh; in this case they are both 24.  This line is
followed by 24 lines, each containing 24 triples of numbers.  Each of
these triples is a point on the surface.  Then finally there is a line
with "@code{@})}" on it that ends the "@code{@{}" which began the
@code{define} statement and the "@code{(}" that began the command.  For
more details on the format of MESH data, @pxref{MESH}.

This module could be written without the use of handles by having it
write out commands of the form

@example
(geometry example @{
MESH
24 24
@dots{}
@})
@end example

@noindent
This first time Geomview receives a command of this form it would create
a geom called @code{example} with the given @code{MESH} data.
Subsequent @code{(geometry example @dots{})} commands would cause
Geomview to replace the geometry of the geom @code{example} with the new
@code{MESH} data.  If done in this way there would be no need to send
the initial @code{(geometry example @{ : foo @})} command as above.  The
handle technique is useful, however, because it can be used in more
general situations where a handle represents only part of a complex
geom, allowing an external module to replace only that part without
having to retransmit the entire geom.  For more information on handles,
@xref{GCL}.

The module loops through calls to @code{UpdateMesh} which print out
commands of the above form one after the other as fast as possible.
The loop continues indefinitely; the module will terminate when the
user kills it by clicking on its instance line in the @widget{Modules}
browser, or else when Geomview exits.

Sometimes when you terminate this module by clicking on its instance
entry the @widget{Modules} browser, Geomview will kill it while it is in
the middle of sending a command to Geomview.  Geomview will then receive
only a piece of a command and will print out a cryptic but harmless
error message about this.  When a module has a user interface panel
it can use a "Quit" button to provide a more graceful way for the user
to terminate the module.  See the next example.

You can run this module in a shell window without Geomview to see the
commands it prints out.  You will have to kill it with
@kbd{ctrl-C} to get it to stop.

@comment ================================================================
@node Example2,Forms,Example1,Modules
@section Example 2: Simple External Module with FORMS Control Panel

This section gives a new version of the above module --- one that
includes a user interface panel for controlling the velocity of the
oscillation.  We use the FORMS library by Mark Overmars for the control
panel.  The FORMS library is a public domain user interface toolkit for
IRISes; for more information @xref{Forms}.

To try out this example, make a copy of the file
@file{example2.c} (distributed with Geomview in the @file{doc}
subdirectory) in your directory and compile it with the command

@example
cc -I/u/gcg/ngrap/include -o example2 example2.c \
  -L/u/gcg/ngrap/lib/sgi -lforms -lfm_s -lgl_s -lm
@end example

If you are not using the Geometry Center's computer system you should
replace the string @file{/u/gcg/ngrap} above with the pathname of the
Geomview distribution directory on your system.  (The forms library is
distributed with Geomview and the @code{-I} and @code{-L} options above
tell the compiler where to find it.)

Then put the line

@example
(emodule-define "Example 2" "./example2")
@end example

@noindent
in a file called @file{.geomview} in the current directory and invoke
Geomview from that directory.  Click on the "Example 2" entry in the
@widget{Modules} browser to invoke the module.  A small control panel
should appear.  You can then control the velocity of the mesh
oscillation by moving the slider.

@example
@comment #include "example2.c"
/*
 * example2.c: oscillating mesh with FORMS control panel
 *
 * This example module is distributed with the Geomview manual.
 * If you are not reading this in the manual, see the "External
 * Modules" chapter of the manual for an explanation.
 *
 * This module creates an oscillating mesh and has a FORMS control
 * panel that lets you change the speed of the oscillation with a
 * slider.
 */

#include <math.h>
#include <stdio.h>
#include <sys/time.h>           /* for struct timeval below */

#include "forms.h"              /* for FORMS library */

FL@_FORM *OurForm;
FL@_OBJECT *VelocitySlider;
float dt;

/* F is the function that we plot
 */
float F(x,y,t)
     float x,y,t;
@{
  float r = sqrt(x*x+y*y);
  return(sin(r + t)*sqrt(r));
@}

/* SetVelocity is the slider callback procedure; FORMS calls this
 * when the user moves the slider bar.
 */
void SetVelocity(FL@_OBJECT *obj, long val)
@{
  dt = fl@_get@_slider@_value(VelocitySlider);
@}

/* Quit is the "Quit" button callback procedure; FORMS calls this
 * when the user clicks the "Quit" button.
 */
void Quit(FL@_OBJECT *obj, long val)
@{
  exit(0);
@}

/* create@_form@_OurForm() creates the FORMS panel by calling a bunch of
 * procedures in the FORMS library.  This code was generated
 * automatically by the FORMS designer program; normally this code
 * would be in a separate file which you would not edit by hand.  For
 * simplicity of this example, however, we include this code here.
 */
create@_form@_OurForm()
@{
  FL@_OBJECT *obj;
  FL@_FORM *form;
  OurForm = form = fl@_bgn@_form(FL@_NO@_BOX,380.0,120.0);
  obj = fl@_add@_box(FL@_UP@_BOX,0.0,0.0,380.0,120.0,"");
  VelocitySlider = obj = fl@_add@_valslider(FL@_HOR@_SLIDER,20.0,30.0,
                                          340.0,40.0,"Velocity");
    fl@_set@_object@_lsize(obj,FL@_LARGE@_FONT);
    fl@_set@_object@_align(obj,FL@_ALIGN@_TOP);
    fl@_set@_call@_back(obj,SetVelocity,0);
  obj = fl@_add@_button(FL@_NORMAL@_BUTTON,290.0,75.0,70.0,35.0,"Quit");
    fl@_set@_object@_lsize(obj,FL@_LARGE@_FONT);
    fl@_set@_call@_back(obj,Quit,0);
  fl@_end@_form();
@}

main(argc, argv)        
     char **argv;
@{
  int xdim, ydim;
  float xmin, xmax, ymin, ymax, dx, dy, t;
  int fdmask;
  static struct timeval timeout = @{0, 200000@};

  xmin = ymin = -5;             /* Set x and y            */
  xmax = ymax = 5;              /*    plot ranges         */
  xdim = ydim = 24;             /* Set x and y resolution */
  dt = 0.1;                     /* Time increment is 0.1  */

  /* Forms panel setup.
   */
  foreground();
  create@_form@_OurForm();
  fl@_set@_slider@_bounds(VelocitySlider, 0.0, 1.0);
  fl@_set@_slider@_value(VelocitySlider, dt);
  fl@_show@_form(OurForm, FL@_PLACE@_SIZE, TRUE, "Example 2");


  /* Geomview setup.
   */
  printf("(geometry example @{ : foo @})\n");
  fflush(stdout);

  /* Loop until killed.
   */
  for (t=0; ; t+=dt) @{
    fdmask = (1 << fileno(stdin)) | (1 << qgetfd());
    select(qgetfd()+1, &fdmask, NULL, NULL, &timeout);
    fl@_check@_forms();
    UpdateMesh(xmin, xmax, ymin, ymax, xdim, ydim, t);
  @}
@}

/* UpdateMesh sends one mesh iteration to Geomview
 */
UpdateMesh(xmin, xmax, ymin, ymax, xdim, ydim, t)
     float xmin, xmax, ymin, ymax, t;
     int xdim, ydim;
@{
  int i,j;
  float x,y, dx,dy;

  dx = (xmax-xmin)/(xdim-1);
  dy = (ymax-ymin)/(ydim-1);

  printf("(read geometry @{ define foo \n");
  printf("MESH\n");
  printf("%1d %1d\n", xdim, ydim);
  for (j=0, y = ymin; j<ydim; ++j, y += dy) @{
    for (i=0, x = xmin; i<xdim; ++i, x += dx) @{
      printf("%f %f %f\t", x, y, F(x,y,t));
    @}
    printf("\n");
  @}
  printf("@})\n");
  fflush(stdout);
@}
@comment #end include
@end example

The code begins by including some header files needed for the event loop
and the FORMS library.  It then declares global variables for holding a
pointer to the slider FORMS object and the velocity @code{dt}.  These
are global because they are needed in the slider callback procedure
@code{SetVelocity}, which forms calls every time the user moves the
slider bar. @code{SetVelocity} sets @code{dt} to be the new value of the
slider.

@code{Quit} is the callback procedure for the @widget{Quit} button;
it provides a graceful way for the user to terminate the program.

The procedure @code{create_panel} calls a bunch of FORMS library
procedures to set up the control panel with slider and button.  For more
information on using FORMS to create interface panels see the FORMS
documentation.  In particular, FORMS comes with a graphical panel
designer that lets you design your panels interactively and generates
code like that in @code{create_panel}.

This example's main program is similar to the previous example, but
includes extra code to deal with setting up and managing the FORMS
panel.  

To set up the panel we call the GL procedure @code{foreground} to cause
the process to run in the foreground.  By default GL programs run in the
background, and for various reasons external modules that use FORMS
(which is based on GL) need to run in the foreground.  We then call
@code{create_panel} to create the panel and @code{fl_set_slider_value}
to set the initial value of the slider.  The call to @code{fl_show_form}
causes the panel to appear on the screen.

The first three lines of the main loop, starting with 
@example
fdmask = (1 << fileno(stdin)) | (1 << qgetfd());
@end example
@noindent
check for and deal with events in the panel.  The call to @code{select}
imposes a delay on each pass through the main loop.  This call returns
either after a delay of 1/5 second or when the next GL event occurs, or
when data appears on standard input, whichever comes first.  The
@code{timeout} variable specifies the amount of time to wait on this
call; the first member (0 in this example) gives the number of seconds,
and the second member (200000 in this example) gives the number of
microseconds.  Finally, @code{fl_check_forms()} checks for and processes
any FORMS events that have happened; in this case this means calling
@code{SetVelocity} if the user has moved the slider or calling
@code{Quit} if the user has clicked on the @widget{Quit} button.

The purpose of the delay in the loop is to keep the program from using
excessive amounts of CPU time running around its main loop when there
are no events to be processed.  This is not so crucial in this example,
and in fact may actually slow down the animation somewhat, but in
general with external modules that have event loops it is important to
do something like this because otherwise the module will needlessly take
CPU cycles away from other running programs (such as Geomview!)  even
when it isn't doing anything.

The last line of the main loop in this example, the call to
@code{UpdateMesh}, is the same as in the previous example.

@comment ================================================================
@node Forms,Example3,Example2,Modules
@section The FORMS Library

Geomview itself is written using Mark Overmar's public domain FORMS
library.  FORMS is a handy and relatively simple user interface toolkit
for IRISes.  Many Geomview external modules, including the examples in
this manual, use FORMS to create and manage control panels.

We distribute a version of the FORMS library with Geomview because it is
necessary in order to compile Geomview and many of our modules.  If you
use FORMS to write Geomview modules (or anything else, for that matter)
you may use this copy.  The header file @file{forms.h} is in the
@file{include} subdirectory, and the library file @file{libforms.a} is
in the @file{lib/sgi} subdirectory (these are subdirectories of the
Geomview distribution directory, @file{/u/gcg/ngrap} on the Geometry
Center's system).  In particular, you can link the example modules in
this manual using this copy.

FORMS is available via ftp on the Internet from a variety of sites,
including @code{cs.ruu.nl} or @code{glaurung.physics.mcgill.ca}.  It
comes with source code and extensive documentation.

If you wish you may use any other interface toolkit instead of FORMS in
an external module.  We chose FORMS because it is free and relatively
simple.


@comment ================================================================
@node Example3,Module Installation,Forms,Modules
@section Example 3: External Module with Bi-Directional Communication

The previous two example modules simply send commands to Geomview and do
not receive anything from Geomview.  This section describes a module
that communicates in both directions.  There are two types of
communication that can go from Geomview to an external module.  This
example shows @emph{asynchronous} communication --- the module needs to
be able to respond at any moment to expressions that Geomview may emit
which inform the module of some change of state within Geomview.

(The other type of communication is @emph{synchronous}, where a module
sends a request to Geomview for some piece of information and waits for
a response to come back before doing anything else.  The main gcl
command for requesting information of this type is @code{write}.  This
module does not do any synchronous communication.)

In ansynchronous communication, Geomview sends expressions that are
essentially echoes of gcl commands.  The external module sends
Geomview a command expressing interest in a certain command, and then
every time Geomview executes that command, the module receives a copy of
it.  This happens regardless of who sent the command to Geomview; it can
be the result of the user doing something with a Geomview panel, or
it may have come from another module or from a file that Geomview reads.
This is how a module can find out about and act on things that happen in
Geomview.

This example uses the OOGL lisp library to parse and act on the
expressions that Geomview writes to the module's standard input.  This
library is actually part of Geomview itself --- we wrote the library in
the process of implementing gcl.  It is also convenient to use it in
external modules that must understand a of subset of gcl ---
specifically, those commands that the module has expressed interest in.

This example shows how a module can receive user pick events, i.e.
when the user clicks the right mouse button with the cursor over a geom
in a Geomview camera window.  When this happens Geomview generates an
internal call to a procedure called @code{pick}; the arguments to the
procedure give information about the pick, such as what object was
picked, the coordinates of the picked point, etc.  If an external module
has expressed interest in calls to @code{pick}, then whenever
@code{pick} is called Geomview will echo the call to the module's
standard input.  The module can then do whatever it wants with the pick
information.

This module is the same as the @emph{Nose} module that comes with
Geomview.  Its purpose is to illustrate picking.  Whenever you pick on a
geom by clicking the right mouse button on it, the module draws a little
box at the spot where you clicked.  Usually the box is yellow.  If you
pick a vertex, the box is colored magenta.  If you pick a point on an
edge of an object, the module will also highlight the edge by drawing
cyan boxes at its endpoints and drawing a yellow line along the edge.

Note that in order for this module to actually do anything you must have
a geom loaded into Geomview and you must click the right mouse button
with the cursor over a part of the geom.

@example
@comment #include "example3.c"
/*
 * example3.c: external module with bi-directional communication
 *
 * This example module is distributed with the Geomview manual.
 * If you are not reading this in the manual, see the "External
 * Modules" chapter of the manual for an explanation.
 *
 * This module is the same as the "Nose" program that is distributed
 * with Geomview.  It illustrates how a module can find out about
 * and respond to user pick events in Geomview.  It draws a little box
 * at the point where a pick occurrs.  The box is yellow if it is not
 * at a vertex, and magenta if it is on a vertex.  If it is on an edge,
 * the program also marks the edge.
 *
 * To compile:
 *
 *   cc -I/u/gcg/ngrap/include -g -o example3 example3.c \
 *      -L/u/gcg/ngrap/lib/sgi -loogl -lm
 *
 * If you are not on the Geometry Center's system you should replace
 * "/u/gcg/ngrap" above with the pathname of the Geomview distribution
 * directory on your system.
 */

#include <stdio.h>
#include "lisp.h"               /* We use the OOGL lisp library */
#include "pickfunc.h"           /* for PICKFUNC below */
#include "3d.h"                 /* for 3d geometry library */

/* boxstring gives the OOGL data to define the little box that
 * we draw at the pick point.  NOTE:  It is very important to
 * have a newline at the end of the OFF object in this string.
 */
char boxstring[] = "\
INST\n\
transform\n\
.04 0 0 0\n\
0 .04 0 0\n\
0 0 .04 0\n\
0 0 0 1\n\
geom\n\
OFF\n\
8 6 12\n\
\n\
-.5 -.5 -.5     # 0   \n\
.5 -.5 -.5      # 1   \n\
.5  .5 -.5      # 2   \n\
-.5  .5 -.5     # 3   \n\
-.5 -.5  .5     # 4   \n\
.5 -.5  .5      # 5   \n\
.5  .5  .5      # 6   \n\
-.5  .5  .5     # 7   \n\
\n\
4 0 1 2 3\n\
4 4 5 6 7\n\
4 2 3 7 6\n\
4 0 1 5 4\n\
4 0 4 7 3\n\
4 1 2 6 5\n";

progn()
@{
  printf("(progn\n");
@}

endprogn()
@{
  printf(")\n");
  fflush(stdout);
@}

Initialize()
@{
  extern LObject *Lpick();  /* This is defined by PICKFUNC below but must */
  			    /* be used in the following LDefun() call */
  LInit();
  LDefun("pick", Lpick, NULL);

  progn(); @{
    /* Define handle "littlebox" for use later
     */
    printf("(read geometry @{ define littlebox @{ %s @}@})\n", boxstring);

    /* Express interest in pick events; see Geomview manual for explanation.
     */
    printf("(interest (pick world * * * * nil nil nil nil nil))\n");

    /* Define "pick" object, initially the empty list (= null object).
     * We replace this later upon receiving a pick event.
     */
    printf("(geometry \"pick\" @{ LIST @} )\n");

    /* Make the "pick" object be non-pickable.
     */
    printf("(pickable \"pick\" no)\n");

    /* Turn off normalization, so that our pick object will appear in the
     * right place.
     */
    printf("(normalization \"pick\" none)\n");

    /* Don't draw the pick object's bounding box.
     */
    printf("(bbox-draw \"pick\" off)\n");

  @} endprogn();
@}

/* The following is a macro call that defines a procedure called
 * Lpick().  The reason for doing this in a macro is that that macro
 * encapsulates a lot of necessary stuff that would be the same for
 * this procedure in any program.  If you write a Geomview module that
 * wants to know about user pick events you can just copy this macro
 * call and change the body to suit your needs; the body is the last
 * argument to the macro and is delimited by curly braces.
 *
 * The first argument to the macro is the name of the procedure to
 * be defined, "Lpick".
 *
 * The next two arguments are numbers which specify the sizes that
 * certain arrays inside the body of the procedure should have.
 * These arrays are used for storing the face and path information
 * of the picked object.  In this module we don't care about this
 * information so we declare them to have length 1, the minimum
 * allowed.
 *
 * The last argument is a block of code to be executed when the module
 * receives a pick event.  In this body you can refer to certain local
 * variables that hold information about the pick.  For details see
 * Example 3 in the Extenal Modules chapter of the Geomview manual.
 */
PICKFUNC(Lpick, 1, 1,
@{           
  handle@_pick(pn>0, &point, vn>0, &vertex, en>0, edge);
@})

handle@_pick(picked, p, vert, v, edge, e)
     int picked;                /* was something actually picked?     */
     int vert;                  /* was the pick near a vertex?        */
     int edge;                  /* was the pick near an edge?         */
     HPoint3 *p;                /* coords of pick point               */
     HPoint3 *v;                /* coords of picked vertex            */
     HPoint3 e[2];              /* coords of endpoints of picked edge */
@{
  Normalize(&e[0]);             /* Normalize makes 4th coord 1.0 */
  Normalize(&e[1]);
  Normalize(p);
  progn(); @{
    if (!picked) @{
      printf("(geometry \"pick\" @{ LIST @} )\n");
    @} else @{
      /*
       * Put the box in place, and color it magenta if it's on a vertex,
       * yellow if not.
       */
      printf("(xform-set pick @{ 1 0 0 0  0 1 0 0  0 0 1 0  %g %g %g 1 @})\n",
             p->x, p->y, p->z);
      printf("(geometry \"pick\"\n");
      if (vert) printf("@{ appearance @{ material @{ diffuse 1 0 1 @} @}\n");
      else printf("@{ appearance @{ material @{ diffuse 1 1 0 @} @}\n");
      printf("  @{ LIST @{ :littlebox @}\n");
      
      /*
       * If it's on an edge and not a vertex, mark the edge
       * with cyan boxes at the endpoins and a black line
       * along the edge.
       */
      if (edge && !vert) @{
        e[0].x -= p->x; e[0].y -= p->y; e[0].z -= p->z;
        e[1].x -= p->x; e[1].y -= p->y; e[1].z -= p->z;
        printf("@{ appearance @{ material @{ diffuse 0 1 1 @} @}\n\
  LIST\n\
   @{ INST transform 1 0 0 0 0 1 0 0 0 0 1 0 %f %f %f 1 geom :littlebox @}\n\
   @{ INST transform 1 0 0 0 0 1 0 0 0 0 1 0 %f %f %f 1 geom :littlebox @}\n\
   @{ VECT\n\
          1 2 1\n\
          2\n\
          1\n\
          %f %f %f\n\
          %f %f %f\n\
          1 1 0 1\n\
   @}\n\
  @}\n",
               e[0].x, e[0].y, e[0].z,
               e[1].x, e[1].y, e[1].z,
               e[0].x, e[0].y, e[0].z,
               e[1].x, e[1].y, e[1].z);
      @}
      printf("    @}\n  @}\n)\n");
    @}

  @} endprogn();

@}

Normalize(HPoint3 *p)
@{
  if (p->w != 0) @{
    p->x /= p->w;
    p->y /= p->w;
    p->z /= p->w;
    p->w = 1;
  @}
@}

main()
@{
  Lake *lake;
  LObject *lit, *val;
  extern char *getenv();

  Initialize();

  lake = LakeDefine(stdin, stdout, NULL);
  while (!feof(stdin)) @{

    /* Parse next lisp expression from stdin.
     */
    lit = LSexpr(lake);

    /* Evaluate that expression; this is where Lpick() gets called.
     */
    val = LEval(lit);

    /* Free the two expressions from above.
     */
    LFree(lit);
    LFree(val);
  @}
@}
@comment #end include
@end example

The code begins by defining procedures @code{progn()} and
@code{endprogn()} which begin and end a Geomview @code{progn} group.
The purpose of the Geomview @code{progn} command is to group commands
together and cause Geomview to execute them all at once, without
refreshing any graphics windows until the end.  It is a good idea to
group blocks of commands that a module sends to Geomview like this so
that the user sees their cumulative effect all at once.

Procedure @code{Initialize()} does various things needed at program
startup time.  It initializes the lisp library by calling
@code{LInit()}.  Any program that uses the lisp library should call this
once before calling any other lisp library functions.  It then calls
@code{LDefun} to tell the library about our @code{pick} procedure, which
is defined further down with a call to the @code{DEFPICKFUNC} macro.
Then it sends a bunch of setup commands to Geomview, grouped in a
@code{progn} block.  This includes defining a handle called @code{littlebox}
that stores the geometry of the little box.  Next it sends the command

@example
(interest (pick world * * * * nil nil nil nil nil))
@end example

@noindent
which tells Geomview to notify us when a pick event happens.

The syntax of this @code{interest} statement merits some explanation.
In general @code{interest} takes one argument which is a (parenthesized)
expression representing a Geomview function call.  It specifies a type
of call that the module is interested in knowing about.  The arguments
can be any particular argument values, or the special symbols @code{*}
or @code{nil}.  For example, the first argument in the @code{pick}
expression above is @code{world}.  This means that the module is
interested in calls to @code{pick} where the first argument, which
specifies the coordinate system, is @code{world}.  A @code{*} is like a
wild-card; it means that the module is interested in calls where the
corresponding argument has any value.  The word @code{nil} is like
@code{*}, except that the argument's value is not reported to the
module.  This is useful for cutting down on the amount of data that must
be transmitted in cases where there are arguments that the module
doesn't care about.

The second, third, fourth, and fifth arguments to the @code{pick}
command give the name, pick point coordinates, vertex coordinates, and
edge coordinates of a pick event.  We specify these by @code{*}'s above.
The remaining five arguments to the @code{pick} command give other
information about the pick event that we do not care about in this
module, so we specify these with @code{nil}'s.  For the details of the
arguments to @code{pick}, @xref{GCL}.

The @code{geometry} statement defines a geom called @code{pick} that is
initially an empty list, specified as @code{ @{ LIST @} }; this is the
best way of specifying a null geom.  The module will replace this with
something useful by sending Geomview another @code{geometry} command
when the user picks something.  Next we arrange for the @code{pick}
object to be non-pickable, and turn normalization off for it so that
Geomview will display it in the size and location where we put it,
rather than resizing and relocating it to fit into the unit cube.

The next function in the file, @code{Lpick}, is defined with a strange
looking call to a macro called @code{PICKFUNC}, defined in the header
file @file{pickfunc.h}.  This is the function for handling pick events.
The reason we provide a macro for this is that that macro encapsulates a
lot of necessary stuff that would be the same for the pick-handling
function in any program.  If you write a Geomview module that wants to
know about user pick events you can just copy this macro call and change
it to suit yours needs.

In general the syntax for @code{PICKFUNC} is
@example
PICKFUNC(@var{name}, @var{maxfaceverts}, @var{maxpathlen}, @var{block})
@end example
@noindent
where @var{name} is the name of the procedure to be defined, in this
case @code{Lpick}.  The next two arguments, @var{maxfaceverts} and
@var{maxpathlen}, give the sizes to be used for declaring two local
variable arrays in the body of the procedure.  These arrays are for
storing information about the picked face and the picked primitive's
path.  In this module we don't care about this information (it
corresponds to some of the things masked out by the @code{nil}'s in the
@code{interest} call above) so we specify 1, the minimum allowable, for
both of these.  The last argument, @var{block}, is a block of code to be
executed when a pick event occurs.  The @var{block} should be delimited
by curly braces.  The code in your @var{block} should not include
any @code{return} statements.

@code{PICKFUNC} declares certain local variables in the body of the
procedure.  When the module receives a @code{(pick @dots{})} statement
from Geomview, the procedure assigns values to these variables based on
the information in the @code{pick} call.  (Variables corresponding to
@code{nil}'s in the @code{(interest (pick @dots{}))} are not given
values.)
These variables are:
@table @asis

@item @code{char *coordsys;}
A string specifying the coordinate system in which coordinates are
given.  In this example, this will always be @code{world} because
of the @code{interest} call above.

@item @code{char *id;}
A string specifying the name of the picked geom.

@item @code{HPoint3 point; int pn;}
@code{point} is an @code{HPoint3} structure giving the coordinates of
the picked point.  @code{HPoint3} is a homogeneous point coordinate
representation eqivalent to an array of 4 floats.  @code{pn} tells how
many coordinates have been written into this array; it will always be
either 0 or 4.  A value of zero means no point was picked, i.e. the user
clicked the right mouse button while the cursor was not pointing at a
geom.

@item @code{HPoint3 vertex; int vn;}
@code{vertex} is an @code{HPoint3} structure giving the coordinates of
the picked vertex, if the pick point was near a vertex.  @code{vn} tells
how many coordinates have been written into this array; it will always
be either 0 or 4.  A value of zero means the pick point was not near a
vertex.

@item @code{HPoint3 edge[2]; int en;}
@code{edge} is an array of two @code{HPoint3} structures giving the
coordinates of the endpoints of the picked edge, if the pick point was
near an edge.  @code{en} tells how many coordinates have been written
into this array; it will always be either 0 or 8.  A value of zero means
the pick point was not near an edge.

@end table

In this example module, the remaining variables will never be given
values because their values in the @code{interest} statement were
specified as @code{nil}.   

@table @asis

@item @code{HPoint3 face[@var{maxfaceverts}]; int fn;}
@code{face} is an array of @var{maxfaceverts} @code{HPoint3}'s;
@var{maxfaceverts} is the value specified in the @code{PICKFUNC} call.
@code{face} gives the coordinates of the vertices of the picked face.
@code{fn} tells how many coordinates have been written into this array;
it will always be a multiple of 4 and will be at most
4*@var{maxfaceverts}.  A value of zero means the pick point was not near
a face.

@item @code{HPoint3 ppath[@var{maxpathlen}; int ppn;}
@code{ppath} is an array of @var{maxpathlen} @code{int}'s;
@var{maxpathlen} is the value specified in the @code{PICKFUNC} call.
@code{ppath} gives the path through the OOGL heirarchy to the picked
primitive.  @code{pn} tells how many integers have been written into
this array; it will be at most @var{maxpathlen}.  A path of {3,1,2},
for example, means that the picked primitive is "subobject number 2
of subobject number 1 of object 3 in the world".

@item @code{int vi;}
@code{vi} gives the index of the picked vertex in the picked primitive,
if the pick point was near a vertex.

@item @code{int ei[2]; int ein}
The @code{ei} array gives the indices of the endpoints of the picked
edge, if the pick point was near a vertex.  @code{ein} tells how many
integers were written into this array.  It will always be either 0 or 2;
a value of 0 means the pick point was not near an edge.

@item @code{int fi;}
@code{fi} gives the index of the picked face in the picked primitive, if
the pick point was near a face.

@end table

The @code{handle_pick} procedure actually does the work of dealing with
the pick event.  It begins by normalizing the homogeneous coordinates
passed in as arguments so that we can assume the fourth coordinate is 1.
It then sends gcl commands to define the @code{pick} object to be
whatever is appropriate for the kind of pick recieved.  See @pxref{OOGL
File Formats}, and @pxref{GCL}, for an explanation of the
format of the data in these commands.

The main program, at the bottom of the file, first calls
@code{Initialize()}.  Next, the call to @code{LakeDefine} defines the
@code{Lake} that the lisp library will use.  A @code{Lake} is a
structure that the lisp library uses internally as a type of
communiation vehicle.  (It is like a unix stream but more general, hence
the name.)  This call to @code{LakeDefine} defines a @code{Lake}
structure for doing I/O with @code{stdin} and @code{stdout}.  The third
argument to @code{LakeDefine} should be @code{NULL} for external modules
(it is used by Geomview).  Finally, the program enters its main loop
which parses and evaluates expressions from standard input.

@comment ****************************************************************
@node Module Installation,Private Module Installation,Example3,Modules
@section Module Installation

This section tells how to install an external module so you can invoke
it within Geomview.  There are two ways to install a module: you can
install a @emph{private} module so that the module is available to you
whenever you run Geomview, or you can install a @emph{system} module
so that the module is available to all users on your system whenever they
run Geomview.

@menu
* Private Module Installation::.
* System Module Installation::.
@end menu


@comment ----------------------------------------------------------------
@node Private Module Installation,System Module Installation,Module Installation,Module Installation
@subsection Private Module Installation

The @code{emodule-define} command arranges for a module to appear in
Geomview's @widget{Modules} browser.  @code{emodule-define} takes two
string arguments; the first is the name that will appear in the
@widget{Modules} browser.  The second is the shell command for running
the module; it may include arguments.  Geomview executes this command in
a subshell when you click on the module's entry in the browser.  For
example

@example
(emodule-define "Foo" "/u/home/modules/foo -x")
@end example

@noindent
adds a line labeled "Foo" to the @widget{Modules} browser which
causes the command "/u/home/modules/foo -x" to be executed when selected.

You may put @code{emodule-define} commands in your @file{~/.geomview}
file to arrange for certain modules to be available every time you run
Geomview; @xref{Customization}.  You can also execute
@code{emodule-define} commands from the @widget{Commands} panel if you
want to add a module to an already running copy of Geomview.

There are several other gcl commands for controlling the entries
in the @widget{Modules} browser; for details, @xref{GCL}.

@comment ----------------------------------------------------------------
@node System Module Installation,GCL,Private Module Installation,Module Installation
@subsection System Module Installation

To install a module so that it is available to all Geomview users do
the following

@table @asis

@item 1
Create a file called @file{.geomview-@var{module}} where
@file{@var{module}} is the name of the module.  This file should contain
a single line which is an @code{emodule-define} command for that module:
@example
(emodule-define "New Module" "newmodule")
@end example
The first argument, @code{"New Module"} above, is the string that will
appear in the @widget{Modules} browser.  The second string,
@code{"newmodule"} above, is the shell command for invoking the module.
It may include arguments, and you may assume that the module is on the
@$path searched by the shell.

@item 2
Put a copy of the @file{.geomview-@var{module}} and the module
executable itself in Geomview's @file{modules/sgi} directory.  This is a
subdirectory of the Geomview distribution directory (on the Geometry
Center's system the pathname is @file{/u/gcg/ngrap/modules/sgi}.

@end table

After these steps, the new module should appear, in alphabetical
position, in the @widget{Modules} browser of Geomview's @panel{Main}
panel next time Geomview is run.  The reason this works is that when
Geomview is invoked it processes all the @file{.geomview-*} files in its
@file{modules} directory.  It also remembers the pathname of this
directory and prepends that path to the @$path of the shell in which it
invokes such a module.

@comment ****************************************************************
@node GCL,Argument Conventions,System Module Installation,Top
@chapter gcl: the Geomview Command Language

Gcl has the syntax of lisp -- i.e. an expression of the form (f a b
@dots{}) means pass the values of a, b, @dots{} to the function f.
Gcl is very limited and is by no means an implementation of lisp.  It
is simply a language for expressing commands to be executed in the order
given, rather than a programming language.  It does not support variable
or function definition.

Gcl is the language that Geomview understands for files that it loads
as well as for communication with other programs.  If you want to
execute a gcl command interactively, you can bring up the
@panel{Command} panel which lets you type in a command; Geomview
executes the command when you hit the return key.  Output from such
commands is printed to standard output.  Alternately, you can invoke
Geomview as @code{geomview -c -} which causes it to read gcl commands
from standard input.

Gcl functions return a value, and you can nest function calls in ways
which use this returned value.  For example
@example
(f (g a b))
@end example
evaluates @code{(g a b)} and then evaluates @code{(f x)} where @code{x}
is the result returned by @code{(g a b)}.  Geomview maintains these
return values internally but does not normally print them out.  If you
want to print out a return value pass it to the @code{echo} function.
For example the @code{geomview-version} function returns a string
representing the version of Geomview that is running, and
@example
(echo (geomview-version))
@end example
prints out this string.

Many functions simply return @code{t} for success or @code{nil} for
failure; this is the case if the documentation for the function does not
indicate otherwise.  These are the lisp symbols for true and false,
respectively.  (They correspond to the C variables @code{Lt} and
@code{Lnil} which you are likely to see if you look at the source code
for Geomview or some of the external modules.)

In the descriptions of the commands below several references are made to
"OOGL" formats.  OOGL is the data description language that Geomview
uses for describing geometry, cameras, appearances, and other basic
objects.  For details of the OOGL formats, @xref{OOGL File Formats}.
(Or eqivalently, see the oogl(5) manual page, distributed with Geomview
in the file man/cat5/oogl.5.

The gcl commands and argument types are listed below.  Most
of the documentation in this section of the manual is available within
Geomview via the @code{?} and @code{??} commands.  The command @code{(?
@var{command})} causes Geomview to print out a one-line summary of the
syntax of @var{command}, and @code{(?? @var{command})} prints out an
explanation of what @var{command} does.  You can include the wild-card
character @code{*} in @var{command} to print information for a group of
commands matching a pattern.  For example, @code{(?? *emodule*)} will
print all information about all commands containing the string
@code{emodule}.  @code{(? *)} will print a short list of all commands.

@menu
* Argument Conventions::  Conventions used in describing argument types.
* Gcl Reference::	  Documentation for each gcl command.
@end menu

@node Argument Conventions,Gcl Reference,GCL,GCL
@section Conventions Used In Describing Argument Types

The following symbols are used to describe argument types
in the documentation for gcl functions.

@table @code

@item @var{appearance}
is an OOGL appearance specification.

@item @var{cam-id}
is an @var{id} that refers to a camera.

@item @var{camera}
is an OOGL camera specification.

@item @var{geom-id}
is an @var{id} that refers to a geometry.

@item @var{geometry}
is an OOGL geometry specification.

@item @var{id}
is a string which names a geometry or camera.  Besides
those you create, valid ones are:

@table @code

@item @code{World, world, worldgeom, g0}
the collection of all geom's

@item target
selected target object (cam or geom)

@item center
selected center-of-motion object

@item targetcam
last selected target camera

@item targetgeom
last selected target geom

@item focus
camera where cursor is (or most recently was)

@item allgeoms
all geom objects

@item allcams
all cameras

@item @code{default, defaultcam, prototype}
future cameras inherit default's settings

@end table

The following @var{id}s are used to name coordinate systems,
e.g. in @code{pick} and @code{write} commands:

@table @code

@item @code{World, world, worldgeom, g0}
the world, within which all other geoms live.

@item universe 
the universe, in which the World, lights and cameras live.  Cameras'
world2cam transforms might better be called universe2cam, etc.

@item self
"this Geomview object".  Transform from an object to @code{self} is the
identity; writing its geometry gives the object itself with no
enclosing transform; picked points appear in the object's coordinates.

@item primitive
(for @code{pick} only) Picked points appear in the coordinate system of the
lowest-level OOGL primitive.

@end table

A name is also an acceptable id.  Given names are made unique by
appending numbers if necessary (i.e. "foo<2>"). Every geom is also
named g[n] and every camera is also named c[n] ("g0" is always the
worldgeom): this name is used as a prefix to keyboard commands and can
also be used as a gcl id.  Numbers are reused after an
object is deleted. Both names are shown in the Object browser.

@item @var{statement}
represents a function call.  Function calls have the form @code{(func arg1
arg2 @dots{} )}, where @code{func} is the name of the function and @code{arg1},
@code{arg2}, @dots{} are the arguments.

@item @var{transform}
is an OOGL 4x4 transformation matrix.

@item @var{window}
is an OOGL winddow specification.

@end table

@node Gcl Reference,Non-Euclidean Geometry,Argument Conventions,GCL
@section Gcl Reference Guide

@table @code

@item !
@myfindex  !
@code{!} is a synonym for @code{shell}

@item ?
@myfindex  ?
@code{?} is a synonym for @code{help}

@item ??
@myfindex  ??
@code{??} is a synonym for @code{morehelp}

@item |
@myfindex  |
@code{|} is a synonym for @code{emodule-run}

@myfindex <
@item (< @var{expr1} @var{expr2})
Returns t if @var{expr1} is less than @var{expr2}.  @var{expr1} and
@var{expr2} should be either both integers or floats, or both strings.

@item (= @var{expr1} @var{expr2})
@myfindex =
Returns t if @var{expr1} is equal to @var{expr2}.  @var{expr1} and
@var{expr2} should be either both integers or floats, or both strings.

@item (> @var{expr1} @var{expr2})
@myfindex >
Returns t if @var{expr1} is greater than @var{expr2}.  @var{expr1} and
@var{expr2} should be either both integers or floats, or both strings.

@item (all geometry)
@myfindex all
returns a list of names of all geometry objects.
Use e.g. ``(echo (all geometry))'' to print such a list.

@item (all camera)
returns a list of names of all cameras.

@item (all emodule defined)
returns a list of all defined external modules.

@item (all emodule running)
returns a list of all running external modules.

@item (ap-override [on|off])
@myfindex ap-override
Selects whether appearance controls should override objects' own
settings.  On by default.  With no arguments, returns current setting.


@item (backcolor      @var{cam-id} @var{r} @var{g} @var{b})
@myfindex backcolor
Set the background color of @var{cam-id}; @var{r} @var{g} @var{b} are
numbers between 0 and 1.

@item (bbox-color     @var{geom-id} @var{r} @var{g} @var{b})
@myfindex bbox-color
Set the bounding-box color of @var{geom-id}; @var{r} @var{g} @var{b} are
between 0 and 1.

@item (bbox-draw      @var{geom-id} [yes|no])
@myfindex bbox-draw
Say whether @var{geom-id}'s bounding-box should be drawn; @code{yes} if
omitted.

@item (camera         @var{cam-id} [@var{camera}])
@myfindex camera
Specify data for @var{cam-id}; @var{camera} is a string giving an OOGL
camera specification.  If no camera @var{cam-id} exists,
it is created; in this case, the second argument is optional,
and if omitted, a default camera is used.  See also: new-camera.

@item (camera-draw    @var{cam-id} [yes|no])
@myfindex camera-draw
Say whether or not cameras should be drawn in @var{cam-id}; @code{yes}
if omitted.

@item (camera-prop { @var{geometry} }   [projective])
@myfindex camera-prop
Specify the object to be shown when drawing other cameras.  By default,
this object is drawn with its origin at the camera, and with the camera
looking toward the object's -Z axis.  With the "projective" keyword, the
camera's viewing projection is also applied to the object; this places
the object's Z=-1 and Z=+1 at near and far clipping planes, with the
viewing area -1<={X,Y}<=+1.  Example: (camera-prop { < cube }
projective)

@item (camera-reset   @var{cam-id})
@myfindex camera-reset
Reset @var{cam-id} to its default value.

@item (car LIST)
@myfindex car
returns the first element of LIST.

@item (cdr LIST)
@myfindex cdr
returns the list obtained by removing the first element of LIST.

@item (clock)
@myfindex clock
Returns the current time, in seconds, as shown by this stream's clock.
See also set-clock and sleep-until.

@item (command        INFILE [OUTFILE])
@myfindex command
Read commands from INFILE; send corresponding responses
(e.g. anything written to filename @file{-}) to OUTFILE, stdout
by default.

@item (copy [@var{id}] [name])
@myfindex copy
Copies an object or camera.  If @var{id} is not specified, it 
is assumed to be targetgeom.  If name is not specified, it 
is assumed to be the same as the name of @var{id}.

@item (cull-backface [on|off])
@myfindex cull-backface
Select whether back-facing polygons should be displayed.
Initially on: all polygons are displayed.  When off, polygons whose
vertices are arranged clockwise on the screen are hidden.  Useful for
simulating two-sided surface coloring.

@item (cursor @var{cam-id}  @{on|off@} [pbmfile xorigin yorigin])
@myfindex cursor
Turns the given window's graphics cursor on or off.
Optionally sets the 16x16 pixel cursor glyph from the given file,
which must be in binary (P4) PBM format.  Can only be applied to
actual windows, not e.g. @code{allcams} or @code{default}.  Sorry.

@item (cursor-still [INT])
@myfindex cursor-still
Sets the number of microseconds for which the cursor must not
move to register as holding still.  If INT is not specified,
the value will be reset to the default.

@item (cursor-twitch [INT])
@myfindex cursor-twitch
Sets the distance which the cursor must not move (in x or
y) to register as holding still.  If INT is not specified,
the value will be reset to the default.

@item (delete         @var{id})
@myfindex delete
Delete object or camera @var{id}.

@item (dimension [@var{N}])
@myfindex dimension
Sets or reads the space dimension for @var{N}-dimensional viewing.
(Since calculations are done using homogeneous coordinates, this means
matrices are (@var{N}+1)x(@var{N}+1).)  With no arguments, returns the
current dimension, or 0 if @var{N}-dimensional viewing has not been
enabled.

@item (dice           @var{geom-id} @var{N})
@myfindex dice
Dice any Bezier patches within @var{geom-id} into NxN meshes; default 10.

@item (draw           @var{cam-id})
@myfindex draw
Draw the view in @var{cam-id}, if it needs redrawing.  See also @code{redraw}.

@item (echo          @dots{})
@myfindex echo
Write the given data to the special file @file{-}.  Strings are written
literally; lisp expressions are evaluated and their values written.
If received from an external program, @code{echo} sends to the program's
input.  Otherwise writes to Geomview's own standard output
(typically the terminal).

@item (emodule-clear)
@myfindex emodule-clear
Clears the Geomview application (external module) browser.

@item (emodule-define  @var{name}  @var{shell-command} @dots{})
@myfindex emodule-define
Define an external module called @var{name}, which then appears in the
external-module browser.  The @var{shell-command} string
is a UNIX shell command which invokes the module.
See emodule-run for discussion of external modules.

@item (emodule-defined @var{modulename})
@myfindex emodule-defined
If an external module named @var{modulename} is known, returns the name
of the program invoked when it's run as a quoted string; otherwise
returns @code{nil}.  @code{(echo (emodule-defined @var{modulename}))} prints
the string.

@item (emodule-isrunning @var{name})
@myfindex emodule-isrunning
Returns Lt if the emodule @var{name} is running, or Lnil if it is not running.
@var{name} is searched for in the names as they appear in the browser and in
the shell commands used to execute the external modules (not including
arguements).

@item (emodule-path)
@myfindex emodule-path
Returns the current search path for external modules.
Note: to actually see the value returned by this function
you should wrap it in a call to echo: (echo (emodule-path)).
See also set-emodule-path.

@item (emodule-run  @var{shell-command} @var{args} @dots{})
@myfindex emodule-run
Runs the given @var{shell-command} (a string containing a UNIX shell
command) as an external module.  The module's standard output
is taken as gcl commands; responses (written to filename
@file{-} are sent to the module's standard input.  The shell
command is interpreted by /bin/sh, so e.g. I/O redirection may
be used; a program which prompts the user for input from the
terminal could be run with:
@code{(emodule-run  yourprogram  <&2)}.
If not already set, the environment variable @$MACHTYPE is set
to the name of the machine type.  Input and output
connections to Geomview are dropped when the shell command
terminates.  Clicking on a running program's module-browser entry
sends the signal SIGHUP to the program.  For this to work, programs
should avoid running in the background; those using FORMS or GL
should call foreground() before the first FORMS or winopen() call.
See also emodule-define, emodule-start.

@item (emodule-sort)
@myfindex emodule-sort
Sorts the modules in the @widget{Modules} browser alphabetically.

@item (emodule-start  @var{name})
@myfindex emodule-start
Starts the external module @var{name}, defined by emodule-define.
Equivalent to clicking on the corresponding module-browser entry.

@item (emodule-transmit @var{name} LIST)
@myfindex emodule-transmit
Places LIST into external module @var{name}'s standard input.  @var{name} is
searched for in the names of the modules as they appear in the
External Modules browser and then in the shell commands used to
execute the external modules.  Does nothing if modname is not
running.

@item (escale @var{geom-id} @var{factor})
@myfindex escale
Same as scale but multiplies by exp(scale).  Obsolete.

@item (event-mode @var{modestring})
@myfindex event-mode
Set the mouse event (motion) mode; @var{modestring} should be one of
the strings that appears in the motion mode browser (including
the keyboard shortcut, e.g. "[r] Rotate").

@item (evert @var{geom-id} [yes|no])
@myfindex evert
Set the normal eversion state of @var{geom-id}.  If the second argument
is omitted, toggle the eversion state.

@item (exit)
@myfindex exit
Terminates Geomview.

@item (ezoom @var{geom-id} @var{factor})
@myfindex ezoom
Same as zoom but multiplies by exp(zoom).  Obsolete.

@item (freeze @var{cam-id})
@myfindex freeze
Freeze @var{cam-id}; drawing in this camera's window is turned off
until it is explicitly redrawn with @code{(redraw @var{cam-id})}, after
which time drawing resumes as normal.

@item (geometry @var{geom-id} [@var{geometry}])
@myfindex geometry
Specify the geometry for @var{geom-id}.  @var{geometry} is a string
giving an OOGL geometry specification.  If no object
called @var{geom-id} exists, it is created; in this case the
@var{geometry} argument is optional, and if omitted, the new
object @var{geom-id} is given an empty geometry.

@item (geomview-version)
Returns a string representing the version of Geomview that is
@myfindex geomview-version
running.

@item (hdefine geometry|camera|transform|window @var{name} @var{value})
@myfindex hdefine
Sets the value of a handle of a given type.  (hdefine @var{type}
@var{name} @var{value}) is generally equivalent to @code{(read
@var{type} @{ define @var{name} @var{value} @})} except that the
assignment is done when hdefine is executed, (possibly not at all if
inside a conditional statement), while @code{(read @dots{} define @dots{})}
performs assignment as soon as the text is read.

@item (help  [command])
@myfindex help
Command may include "*"s as wildcards; see also @code{morehelp}.
One-line command help; lists names only if multiple commands match.
@code{?} is a synonym for @code{help}.

@item (hmodel @var{cam-id} @{virtual|projective|conformal@})
@myfindex hmodel
Set the model used to display geometry in
this camera; see also @code{space}.

@item (hsphere-draw   @var{cam-id} [yes|no])
@myfindex hsphere-draw
Say whether to draw the sphere at infinity in hyperbolic space.
If the second argument is omitted, @code{yes} is assumed.

@item (if @var{test} @var{expr1} [@var{expr2}])
@myfindex if
Evaluates @var{test}; if @var{test} returns a non-nil value, returns the
value of @var{expr1}.  If @var{test} returns nil, returns the value of
@var{expr2} if @var{expr2} is present, otherwise returns nil.

@item (inhibit-warning @var{string})
@myfindex inhibit-warning
Inhibit warning inhbits Geomview from displaying a
particular warning message determined by @var{string}.
At present there are no warning messages that this
applies to, so this command is rather useless.

@item (interest (@var{command} [@var{args}]))
@myfindex interest
Allows you to express interest in a command.  When Geomview
executes that command in the future it will echo it to the
communication pool from which the interest command came.
@var{command} can be any command.  Args specify restrictions on the
values of the arguments; if @var{args} are present in the interest
command, Geomview will only echo calls to the command in which
the arguments match those given in the interest command.  Two
special argument values may appear in the argument list.  @code{*}
matches any value. @code{nil} matches any value but supresses the
reporting of that value; its value is reported as @code{nil}.

The purpose of the interest command is to allow external
modules to find out about things happening inside Geomview.
For example, a module interested in knowing when a geom called
"foo" is deleted could say @code{(interest (delete foo))} and would
receive the string @code{(delete foo)} when foo is deleted.

Picking is a special case of this.  For most modules
interested in pick events the command @code{(interest (pick
world))} is sufficient.  This causes Geomview to send a string
of the form @code{(pick world @dots{})} every time a pick event (right
mouse double click).  See the @code{pick} command for details.

@item (lines-closer   @var{cam-id} DIST)
@myfindex lines-closer
Draw lines (including edges) closer to the camera than polygons
by DIST / 10^5  of the Z-buffer range.  DIST = 3.0 by default.
If DIST is too small, a line lying on a surface may be
dotted or invisible, depending on the viewpoint.
If DIST is too large, lines may appear in front of surfaces
that they actually lie behind.  Good values for DIST vary with
the scene, viewpoint, and distance between near and far clipping
planes.  This feature is a kludge, but can be helpful.

@item (load  filename  [command|geometry|camera])
@myfindex load
Loads the given file into Geomview.  The optional second argument
specifies the type of data it contains, which may be @code{command}
(gcl commands), @code{geometry} (OOGL geometric data), or
@code{camera} (OOGL camera definition).  If omitted, attempts to guess
about the file's contents.  Loading geometric data creates a new visible
object; loading a camera opens a new window; loading a gcl file
executes the commands in the file.

@item (load-path)
@myfindex load-path
Returns the current search path for command, geometry, etc. files.
Note: to actually see the value returned by this function
you should wrap it in a call to echo: (echo (load-path)).
See also set-load-path.

@item (look [@var{geom-id}] [@var{cam-id}])
@myfindex look
Rotates the named camera to point toward the center of the 
bounding box of the named object (or the origin in hyperbolic or 
sphereical space).  In Euclidean space, moves the camera 
forward or backward until the object appears as large 
as possible while still being entirely visible.  Equivalent to 
@example
progn ( 
  (look-toward [@var{geom-id}] [@var{cam-id}] @{center | origin@})
  [(look-encompass [@var{geom-id}] [@var{cam-id}])] 
)
@end example
If @var{geom-id} is not specified, it is assumed to be World.  If 
@var{cam-id} is not specified, it is assumed to be targetcam.

@item (look-encompass [@var{geom-id}] [@var{cam-id}])
@myfindex look-encompass
Moves @var{cam-id} backwards or forwards until its field of view
surrounds @var{geom-id}. This routine works only in Euclidean space.  
If @var{geom-id} is not specified, it is assumed to be the world.  
If @var{cam-id} is not specified, it is assumed to be the targetcam.  
See also (look-encompass-size).

@item (look-encompass-size [@var{view-fraction}  @var{clip-ratio}  @var{near-margin} @var{far-margin}])
@myfindex look-encompass-size
Sets/returns parameters used by (look-encompass).
@var{view-fraction} is the portion of the camera window filled by the
object, @var{clip-ratio} is the max allowed ratio of near-to-far
clipping planes.  The near clipping plane is 1/@var{near-margin} times
closer than the near edge of the object, and the far clipping plane is
@var{far-margin} times further away.  Returns the list of current
values.  Defaults: .75 100 0.1 4.0

@item (look-recenter [@var{geom-id}] [@var{cam-id}])
@myfindex look-recenter
Translates and rotates the camera so that it is looking in the 
-z direction (in @var{geom-id}'s coordinate system) at the center of 
@var{geom-id}'s bounding box (or the origin of the coordinate system 
in non-Eudlidean space).  In Euclidean space, the camera is also 
moved as close as possible to the object while allowing the 
entire object to be visible.  Also makes sure that the y-axes of 
@var{geom-id} and @var{cam-id} are parallel.

@item (look-toward [@var{geom-id}] [@var{cam-id}] [origin | center])
@myfindex look-toward
Rotates the named camera to point toward the origin of the
object's coordinate system, or the center of the object's
bounding box (in non-Euclidean space, the origin will be used 
automatically).  Default @var{geom-id} is the world, default camera
is targetcam, default location to point towards is the center
of the bounding box.

@item (merge @{window|camera@} @var{cam-id}  @{ @var{window} or @var{camera} @dots{} @} )
@myfindex merge
Modify the given window or camera, changing just those properties
specified in the last argument.  E.g.
@code{(merge camera "Camera" @{ far 20 @})}
sets Camera's far clipping plane to 20 while leaving
other attributes untouched.

@item (merge-ap @var{geom-id} @var{appearance})
@myfindex merge-ap
Merge in some appearance characteristics to @var{geom-id}.
Appearance parameters include surface and line color, shading
style, line width, and lighting.

@item merge-base-ap
@myfindex merge-base-ap
is a synonym for merge-baseap.

@item (merge-baseap @var{appearance})
@myfindex merge-baseap
Merge in some appearance characteristics to the base default
appearance (applied to every geom before its own apperance).
Lighting is typically included in the base appearance.

@item (morehelp @var{command})
@myfindex morehelp
@var{command} may include "*" wildcards. Prints more info than
@code{(help @var{command})}. @code{??} is a synonym for @code{morehelp}

@item (name-object @var{id} @var{name})
@myfindex name-object
Assign a new @var{name} (a string) to @var{id}.  A number is appended if
that name is in use (for example, "foo" -> "foo<2>").  The new
name, possibly with number appended, may be used as object's
id thereafter.

@item (new-alien name [@var{geometry}])
@myfindex new-alien
Create a new alien (geom not in the world) with the given name
(a string).  @var{geometry} is a string giving an OOGL geometry
specification.  If @var{geometry} is omitted, the new alien
is given an empty geometry.  If an object with that name
already exists, the new alien is given a unique name.  The
light beams that are used to move around the lights are an
example of aliens. They're drawn but are not controllable the
way ordinary objects are: they don't appear in the object
browser and the user can't move them with the normal motion
modes.

@item (new-camera name [@var{camera}])
@myfindex new-camera
Create a new camera with the given name (a string).  If a
camera with that name already exists, the new object is given
a unique name.  If @var{camera} is omitted a default camera is used.

@item (new-center [id])
@myfindex new-center
Stop id, then set id's transform to the identity.  Default id 
is target.  Also, if the id is a camera, calls 
(look-recenter World id).  The main function of the call to 
(look-recenter) is to place the camera so that it is pointing 
parallel to the z axis toward the center of the world.

@item (new-geometry name [@var{geometry}])
@myfindex new-geometry
Create a new geom with the given name (a string).  @var{geometry} is
a string giving an OOGL geometry specification.  If
@var{geometry} is omitted, the new object is given an empty geometry.
If an object with that name already exists, the new object is
given a unique name.

@item (new-reset)
Equivalent to (progn (new-center ALLGEOMS)(new-center ALLCAMS))
@myfindex new-reset

@item (ND-axes @var{cam-id} [@var{clustername} [Xindex Yindex Zindex]])
@myfindex ND-axes
Sets or reads the set of axes in the space of the N-dimensional virtual
camera @var{clustername} which determine the 3-D subspace seen by camera
@var{cam-id}.  Axes are specified by their indices, from 0 to N-1 for an
N-dimensional space.

@item (ND-color @var{cam-id} [ (((x0 x1 x2 ... xn) v r g b a   v r g b a  ... )
	((x0 ... xn)  v r g b a  v r g b a ...) ...)] )
@myfindex ND-color

@item (ND-xform @var{geom-id} [@var{ntransform} { @var{idim} @var{odim} ... }])
@myfindex ND-xform
Sets or returns the N-D transform of the given @var{geom}.

@item (NeXT)
@myfindex NeXT
Returns t if running on a NeXT, nil if not

@item (normalization  @var{geom-id} @{each|none|all|keep@})
@myfindex normalization
Set the normalization status of @var{geom-id}.
@table @code
@item none
suppresses all normalization.

@item each
normalizes the object's bounding box to fit into the unit
sphere, with the center of its bounding box translated
to the origin.  The box is scaled such that its long diagonal,
sqrt((xmax-xmin)^2 + (ymax-ymin)^2 + (zmax-zmin)^2), is 2.

@item all
resembles @code{each}, except when an object is changing
(e.g. when its geometry is being changed by an external program).
Then, @code{each} tightly fits the bounding box around the
object whenever it changes and normalizes accordingly,
while @code{all} normalizes the union of all variants of the object
and normalizes accordingly.

@item keep
leaves the current normalization transform unchanged
when the object changes.

@end table

It may be useful to apply @code{each} or @code{all} normalization apply to the
first version of a changing object to bring it in view, then switch to
@code{keep}.

@item (pick COORDSYS GEOMID G V E F P VI EI FI)
@myfindex pick
The pick command is executed internally in response to pick
events (right mouse double click).

@table @code
@item COORDSYS
coordinate system in which coordinates of the following
arguments are specified.   This can be:
@table @code

@item world
world coord sys

@item self
coord sys of the picked geom (GEOMID)

@item primitive

coord sys of the actual primitive within the picked geom where
the pick occurred.

@end table

@item GEOMID
id of picked geom

@item G
picked point (actual intersection of pick ray with object)

@item V
picked vertex, if any

@item E
picked edge, if any

@item F
picked face

@item P
path to picked primitive [0 or more]

@item VI
index of picked vertex in primitive

@item EI
list of indices of endpoints of picked edge, if any

@item FI
index of picked face

@end table

External modules can find out about pick events by registering
interest in calls to @code{pick} via the @code{interest} command.

@item (pickable       @var{geom-id} @{yes|no@})
@myfindex pickable
Say whether or not @var{geom-id} is included in the pool of objects
that could be returned from the pick command.

@item (position       objectID otherID)
@myfindex position
Set the transform of objectID to that of otherID.

@item (position-at    objectID otherID [center | origin])
@myfindex position-at
Translate objectID to the center of the bounding box or the 
origin of the coordinate system of otherID (parallel translation).
Default is center.

@item (position-toward objectID otherID [center | origin])
@myfindex position-toward
Rotate objectID so that the center of the bounding box
or the origin of the coordinate system of the otherID
lies on the positive z-axis of the first object.  Default is
the center of the bounding box.

@item (progn STATEMENT [ @dots{} ])
@myfindex progn
evaluates each STATEMENT in order and returns the value of the
last one.  Use progn to group a collection of commands together,
forcing them to be treated as a single command.

@item quit
@myfindex quit
is a synonym for @code{exit}.

@item (quote EXPR)
@myfindex quote
returns the symbolic lisp expression EXPR without evaluating it.

@item (rawevent       dev val x y t)
@myfindex rawevent
Enter the specified raw event into the event queue.  The
arguments directly specify the members of the event structure
used internally by Geomview.  This is the lowest level event
handler and is not intended for general use.

@item (rawpick @var{cam-id} X Y)
@myfindex rawpick
Process a pick event in camera @var{cam-id} at location (X,Y) given in
integer pixel coordinates.  This is a low-level procedure not
intended for external use.

@item (read @{geometry|camera|transform|command@} @{@var{geometry} or @var{camera} or @dots{}@})
@myfindex read
Read and interpret the text in @dots{} as containing the
given type of data.  Useful for defining objects using OOGL
reference syntax, e.g.
@example
(geometry  thing @{ INST  transform : T    geom : fred @})
(read  geometry  @{ define fred QUAD 1 0 0  0 1 0  0 0 1  1 0 0 @})
(read  transform @{ define T <myfile@})
@end example

@item (real-id @var{id})
@myfindex real-id
Returns a string canonically identifying the given @var{id},
or @code{nil} if the object does not exist.  Examples:
@example
(if (real-id fred) (delete fred))
@end example
deletes "fred" if it exists but reports no error if it doesn't, and
@example
(if (= (real-id targetgeom) (real-id World)) () (delete targetgeom))
@end example
deletes "targetgeom" if it is different from the World.

@item (redraw         @var{cam-id})
@myfindex redraw
States that the view in @var{cam-id} should be redrawn on the
next pass through the main loop or the next invocation of @code{draw}.

@item (regtable)
@myfindex regtable
shows the internal interest table; for debugging only.

@item (rehash-emodule-path)
@myfindex rehash-emodule-path
Rebuilds the application (external module) browser by reading
all .geomview-* files in all directories on the emodule-path.
Primarily intended for internal use; any applications defined
by (emodule-define @dots{}) commands outside of the .geomview-*
files on the emodule-path will be lost.  Does not sort the
entries in the brower; see (emodule-sort) for that.

@item (replace-geometry @var{geom-id} PART-SPECIFICATION @var{geometry})
@myfindex replace-geometry
Replace a part of the geometry for @var{geom-id}.

@item (rib-display    [frame|tiff] FILEPREFIX)
@myfindex rib-display
Set Renderman display to framebuffer (popup screen window) or a
TIFF format disk file. FILEPREFIX is used to construct
names of the form "prefixNNNN.suffix". (i.e. foo0000.rib)
The number is incremented on every call to @code{rib-snapshot} and
reset to 0000 when @code{rib-display} is called. TIFF files are given
the same prefix and number as the RIB file (i.e. foo0004.rib
generates foo0004.tiff). The default FILEPREFIX is "geom" and
the default format is TIFF. (Note that Geomview just generates a
RIB file, which must then be rendered.)

@item (rib-snapshot   @var{cam-id} [@var{filename}])
@myfindex rib-snapshot
Write Renderman snapshot (in RIB format) of @var{cam-id} to
@var{filename}.  If no filename specified, see @code{rib-display} for
explanation of the filename used.

@item (scale          @var{geom-id} @var{factor} [@var{y-factor} @var{z-factor}])
@myfindex scale
Scale @var{geom-id}, multiplying its size by @var{factor}.  The factors 
should be positive numbers.  If @var{y-factor} and @var{z-factor} are 
present and non-zero, the object is scaled by @var{factor} in x, by 
@var{y-factor} in y, and by @var{z-factor} in z.  If only @var{factor} is present, 
the object is scaled by @var{factor} in x, y, and z.  Scaling only 
really makes sense in Euclidean space.  Mouse-driven scaling in 
other spaces is not allowed;  the scale command may be issued 
in other spaces but should be used with caution because it may 
cause the data to extend beyond the limits of the space.

@item (scene          @var{cam-id} [@var{geometry}])
@myfindex scene
Make @var{cam-id} look at @var{geometry} instead of at the universe.

@item (set-clock @var{time})
@myfindex set-clock
Adjusts the clock for this command stream to read @var{time} (in seconds)
as of the moment the command is received.  See also sleep-until, clock.

@item (set-conformal-refine @var{cmx} [@var{n} [@var{showedges}]])
@myfindex set-conformal-refine
Sets the parameters for the refinement algorithm used in drawing
in the conformal model.  @var{cmx} is the cosine of the maximum angle
an edge can bend before it is refined.  Its value should be between
-1 and 1; the default is 0.95; decreasing its value will cause less
refinement.  @var{n} is the maximum number of iterations of refining;
the default is 6.  @var{showedges}, which should be @code{no} or @code{yes},
determines whether interior edges in the refinement are drawn.

@item (set-emodule-path      (@var{path1} @dots{} @var{pathn}))
@myfindex set-emodule-path
Sets the search path for external modules.  The @var{path}i should
be pathnames of directories containing, for each module, the
module's executable file and a .geomview-<modulename> file
which contains an (emodule-define @dots{}) command for that
module.  This command implicitly calls (rehash-emodule-path)
to rebuild the application brower from the new path setting.

@item (set-load-path      (PATH1 @dots{} PATHN))
@myfindex set-load-path
Sets search path for command, geometry, etc. files.  The PATHi
are strings giving the pathnames of directories
to be searched.

@item (set-motionscale X)
@myfindex set-motionscale
Set the motion scale factor to X (default value 0.5).  These
commands scale their motion by an amount which depends on the
distance from the frame to the center and on the size of the
frame.  Specifically, they scale by
dist + scaleof(frame) * motionscale
where dist is the distance from the center to the frame and
motionscale is the motion scale factor set by this function.
Scaleof(frame) measures the size of the frame object.

@item (setenv  name string)
@myfindex setenv
sets the environment variable ``name'' to the value
``string''; the name is visible to Geomview (as in pathnames
containing @$name) and to processes it creates, e.g. external
modules.

@item (sgi)
@myfindex sgi
Returns t if running on an sgi machine, nil if not

@item (shell         @var{shell-command})
@myfindex shell
Execute the given UNIX @var{shell-command} using /bin/sh.  Geomview
waits for it to complete and will be unresponsive until it does.

@item (sleep_for  TIME)
@myfindex sleep_for
Suspend reading commands from this stream for TIME seconds.
Commands already read will still be executed; ``sleep-for'' inside
``progn'' won't delay execution of the rest of the progn's contents.

@item (sleep-until TIME)
@myfindex sleep-until
Suspend reading commands from this stream until TIME (in seconds).
Commands already read will still be executed; ``sleep-until'' inside
``progn'' won't delay execution of the rest of the progn's contents.
Time is measured according to this stream's clock, as set by
``set-clock''; if never set, the first sleep-until sets it to 0
(so initially (sleep-until TIME) is the same as (sleep-for TIME)).
Returns the number of seconds until TIME.

@item (snapshot       @var{cam-id}     @var{filename})
@myfindex snapshot
Save a snapshot of @var{cam-id} in IRIS rgb image format in file @var{filename}
(a string).   The window is popped above all other windows and
redrawn before taking the snapshot.

@item (soft-shader  @var{cam-id}  @{on|off|toggle@})
@myfindex soft-shader
Select whether to use software or hardware shading in that camera.

@item (space @{euclidean|hyperbolic|spherical@})
@myfindex space
Set the space associated with the world.

@item (stereowin @var{cam-id}  [@var{layout}] [@var{gapsize}])
@myfindex stereowin
Configure @var{cam-id} as a stereo window.  @var{layout} should be one of
@table @code
@item no
entire window is a single pane, stereo disabled
@item horizontal
split left/right: left is stereo eye#0, right is #1.
@item vertical
split top/bottom: bottom is eye#0, top is #1.
@item colored
panes overlap, red is stereo eye#0, cyan is #1.
@end table
A gap of @var{gapsize} pixels is left between subwindows; if omitted,
subwindows are adjacent.  If both @var{layout} and @var{gapsize} are
omitted, e.g.  @code{(stereowin @var{cam-id})}, returns current settings as a
@code{(stereowin @dots{})} command list.  This command doesn't set stereo
projection; use @code{merge camera} or @code{camera} to set the stereyes
transforms, and @code{merge window} or @code{window} to set the pixel aspect
ratio & window position if needed.

@item (time-interests @var{deltatime} @var{initial} @var{prefix} [@var{suffix}])
@myfindex time-interests
Indicates that all interest-related messages, when separated by at
least @var{deltatime} seconds of real time, should be preceded by
the string @var{prefix} and followed by @var{suffix}; the first message
is preceded by @var{initial}.  All three are printf format strings,
whose argument is the current clock time (in seconds) on that stream.
A @var{deltatime} of zero timestamps every message.  Typical usages:
@example
(time-interests .1 "(set-clock %g)" "(sleep-until %g)")
(time-interests .1 "(set-clock %g)"
"(sleep-until %g) (progn (set-clock %g)" ")")
(time-interests .1 "(set-clock %g)"
"(if (> 0 (sleep-until %g)) (" "))"
@end example

@item (transform      @var{object-id} @var{center-id} @var{frame-id} [rotate|translate|translate-scaled] x y z)
@myfindex transform
Apply a motion (rotation or translation) to object @var{object-id}; that
is, construct and concatenate a transformation matrix with
@var{object-id}'s transform  The 3 @var{id}'s involved are the object
that moves, the center of motion, and the frame of reference
in which to apply the motion.  The center is easiest understood
for rotations: if @var{center-id} is the same as @var{object-id} then it will
spin around its own axes; otherwise the moving object will orbit
the center object.  Normally @var{frame-id}, in whose coordinate system
the (mouse) motions are interpreted, is @code{focus}, the current camera.
Translations can be scaled proportional to the
distance between the target and the center. Support for
spherical and hyperbolic as well as Euclidean space is
built-in: use the "space" command to change spaces.  With type
"rotate" x, y, and z are floats specifying angles in radians.
For types "translate" and "translate-scaled" x, y, and z are
floats specifying distances in the coordinate system of the
center object.

@item (transform-incr  @var{object-id} @var{center-id} @var{frame-id} [rotate|translate|translate-scaled] @var{x} @var{y} @var{z} [@var{dt}])
@myfindex transform-incr
Apply continuing motion: construct a transformation matrix and
concatenate it with the current transform of @var{object-id} every
refresh (sets @var{object-id}'s incremental transform). Same syntax
as transform.  If optional @var{dt} argument is present,
the object is moved at each time step such that its average motion
equals one instance of the motion per @var{dt} seconds.  E.g.
@code{(transform-incr  World World World  rotate  360 0 0  10.0)}
rotates the World about its X axis at 360 degrees every 10 seconds.

@item (transform-set @var{object-id} @var{center-id} @var{frame-id} [rotate|translate|translate-scaled] @var{x} @var{y} @var{z})
@myfindex transform-set
Set @var{objectid}'s transform to the constructed transform.
Same syntax as transform.

@item (ui-center      @var{id})
@myfindex ui-center
Set the center for user interface (i.e. mouse) controlled
motions to object @var{id}.

@item ui-emotion-program
is an obsolete command.  Use its new eqivalent
@code{emodule-define} instead.

@item ui-emotion-run
is an obsolete command.  Use its new eqivalent @code{emodule-start}
instead.

@item (ui-panel       @var{panelname}  @{on|off@} [ @var{window} ] )
@myfindex ui-panel
Do or don't display the given user-interface panel.
Case is ignored in panel names.  Current @var{panelname}s are:
@table @panel
@item geomview
main panel

@item tools
motion controls

@item appearance
appearance controls

@item cameras
camera controls

@item lighting
lighting controls

@item obscure
obscure controls

@item materials
material properties controls

@item command
command entry box

@item credits
Geomview credits

@end table

By default, the @panel{Main} and @panel{Tools} panels appear when
Geomview starts.  If the optional Window is supplied, a
@code{position} clause (e.g. @code{(ui-panel obscure on @{ position xmin
xmax ymin ymax @})} sets the panel's default position.  (Only
xmin and ymin values are actually used.)  A present but empty
Window, e.g.  @code{(ui-panel obscure on @{@})}" causes interactive
positioning.

@item (ui-target      @var{id} [yes|no])
@myfindex ui-target
Set the target of user actions (the selected line of the
target object browser) to @var{id}.  The second argument specifies
whether to make @var{id} the current object regardless of its type.
If @code{no}, then @var{id} becomes the current object of its type
(geom or camera).  The default is @code{yes}.  This command may
result in a change of motion modes based on target choice.

@item (uninterest (@var{command} [@var{args}]))
@myfindex uninterest
Undoes the effect of an @code{interest} command.  (@var{command} [@var{args}]) must
be identical to those used in the @code{interest} command.

@item (update [timestep@_in@_seconds])
@myfindex update
Apply each incremental motion once.  Uses timestep if it's present and
nonzero; otherwise motions are proportional to elapsed real time.

@item (update-draw    @var{cam-id}  [@var{timestep}])
@myfindex update-draw
Apply each incremental motion once and then draw @var{cam-id}.
Applies @var{timestep} seconds' worth of motion, or uses elapsed real
time if @var{timestep} is absent or zero.

@item (window         @var{cam-id}  @var{window})
@myfindex window
Specify attributes for the window of @var{cam-id}, e.g. its size
or initial position, in the OOGL Window syntax.
The special @var{cam-id} @code{default} specifies
properties of future windows (created by @code{camera} or
@code{new-camera}).

@item (winenter       @var{cam-id})
@myfindex winenter
Tell Geomview that the mouse cursor is in the window
of @var{cam-id}.  This function is for development purposes
and is not intended for general use.

@item (write @{command,geometry,camera,transform,window@} @var{filename} [@var{id}|(@var{id} @dots{})] [self|world|universe|other @var{id}])
@myfindex write
write description of @var{id} in given format to @var{filename}.  Last
parameter chooses coordinate system for geometry & transform:
@table @code
@item self
just the object, no transformation or appearance (geometry only)
@item world
the object as positioned within the World.
@item universe
object's position in universal coordinates; includes Worldtransform
@item other @var{id}: the object transformed to @var{id}'s coordinate system.
@end table

A filename of @file{-} is a special case: data are written to the
stream from which the 'write' command was read.  For external
modules, the data are sent to the module's standard input.
For commands not read from an external program, @file{-} means
Geomview's standard output.  (See also the @code{command}
command.)

The @var{id} can either be a single id or a parenthesized list of
ids, like @code{g0} or @code{(g2 g1 dodec.off)}.

@item (write-sexpr     @var{filename} @var{lispobject})
@myfindex write-sexpr
Writes the given @var{lispobject} to @var{filename}. This function is
intended for internal debugging use only.

@item (xform          @var{id} @var{transform})
@myfindex xform
Concatenate @var{transform} with the current transform of the object
(apply @var{transform} to object @var{id}).

@item (xform-incr     @var{id} @var{transform})
@myfindex xform-incr
Apply continual motion: concatenate @var{transform} with the current
transform of the object every refresh (set object ID's
incremental transform to @var{transform}).

@item (xform-set      @var{id} @var{transform})
@myfindex xform-set
Overwrite the current object transform with @var{transform} (set
object ID's transform to @var{transform}).

@item (zoom           @var{cam-id} @var{factor})
@myfindex zoom
Zoom @var{cam-id}, multiplying its field of view by @var{factor}.
@var{factor} should be a positive number.

@end table


@comment ****************************************************************
@node Non-Euclidean Geometry,Mathematica,Gcl Reference,Top
@chapter Non-Euclidean Geometry

Geomview supports hyperbolic and spherical geometry as well as
Euclidean geometry.  The three buttons at the bottom of the @panel{Main}
panel are for setting the current geometry type.

In each of the three geometries, three models are supported:
@widget{Virtual}, @widget{Projective}, and @widget{Conformal}.  You can
change the current model with the @widget{Model} browser on the
@panel{Camera} panel.  Each Geomview camera has its own model setting.

The default model is all three spaces is @widget{Virtual}.  This
corresponds to the camera being in the same space as, and moving under
the same set of transformations as, the geometry itself.

In Euclidean space @widget{Virtual} is the most useful model.
The other models were implemented for hyperbolic and spherical
spaces and just happen to work in Eucldiean space as well:
@widget{Projective} is the same as @widget{Virtual} but by default
displays the unit sphere, and @widget{Conformal} displays everything
inverted in the unit sphere.

In hyperbolic space, the @widget{Projective} model setting gives a view
of the projective ball model of hyperbolic 3-space imbedded in Euclidean
space.  The camera is initially outside the unit ball.  In this model,
the camera moves by Euclidean motions and geometry moves by hyperbolic
motions.  @widget{Conformal} model is similar but shows the conformal
ball model instead. 

In spherical space, the @widget{Projective} model gives a view of half
of the 3-sphere imbedded in Euclidean 3-space.  Spherical motions give
rise to projective transformations in the @widget{Projective} model, and
to
@tex
Mo\"bius
@end tex
@ifinfo
Moebius
@end ifinfo
transformations in the @widget{Conformal} model.  In both of these
models the camera moves by Euclidean motions.

In @widget{Projective} and @widget{Conformal} models, the unit sphere is
drawn by default.  You can turn it off and on at will using the
@widget{Draw Sphere} button in the @panel{Camera} panel.  In the
@widget{Conformal} model, polygons and edges are subdivided as necessary
to make them look curved.  The parameters which determine this
subdivision can be set with the @code{set-conformal-refine} gcl command.

There are several sample hyperbolic space objects in the
@file{data/geom/hyperbolic} subdirectory of the Geomview directory
(@file{/u/gcg/ngrap/data/geom/hyperbolic} on the Geometry Center's
system).  Likewise, the subdirectory @file{data/geom/spherical}
contains several sample spherical space objects.

@comment ****************************************************************
@node Mathematica,OOGL.m,Non-Euclidean Geometry,Top
@chapter Mathematica Graphics in Geomview or RenderMan

Geomview comes with some Mathematica packages that let you use use
Geomview to display Mathematica graphics.  Mathematica is a commercial
mathematical software system available from Wolfram Research, Inc.

There are two ways to do this.
@enumerate
@item
Use Mathematica to write a graphics object to a file in OOGL format
or in RIB format.
@item
Use Geomview as the default display for all 3D graphics output in
Mathematica.
@end enumerate
You can also use these packages to save Mathematica graphics in
RenderMan (RIB) format.

Since the format of Mathematica graphics objects is different from the
OOGL formats, both of these methods involve translating Mathematica
graphics to OOGL format.  Geomview is distributed with a Mathematica
package which does this translation.  Before doing either of the
above you must install this package.

@menu
* OOGL.m::		Generating OOGL files in Mathematica.
* Geomview.m::		Geomview as Mathematica's Default 3D Display.
* RenderMan::		Generating RenderMan files in Mathematica.
* Remote Display::	Using Geomview and Mathematica on different computers.
* Package Details::	Some details about the packages.
* Package Installation::  Installing the Mathematica->Geomview package.
@end menu

@comment ================================================================
@node OOGL.m,Geomview.m,Mathematica,Mathematica
@section Using Mathematica to generate OOGL files

The package @file{OOGL.m} allows Mathematica to write graphics objects
in OOGL format.  To use it, give the command @code{<< OOGL.m} to
Mathematica to load the package.  The
@code{WriteOOGL[@var{file},@var{graphics}]} command writes an OOGL
description of the 3D graphics object @var{graphics} to the file named
@var{file}.@refill

This package also provides the @code{Geomview} command which sends a
3D graphics object to Geomview.  The first time you use this command
it starts up a copy of Geomview.  Later calls send the graphics to the
same Geomview.  There are two ways to use the @code{Geomview} command.

@table @code
@item Geomview[@var{graphics}]
Sends the 3D graphics object @var{graphics} to Geomview as a geom named
@code{Mathematica}.  Subsequent usage of @code{Geomview[@var{graphics}]}
replaces the @code{Mathematica} object in Geomview with the new
@var{graphics}.

@item @code{Geomview[@var{name},@var{graphics}]}
Sends the 3D graphics object @var{graphics} to Geomview as a geom named
@var{name}.  You can use multiple calls of this form with different
names to cause Geomview to display several Mathematica objects at once
and allow independent control over them.
@end table
@example
% math
Mathematica 2.0 for SGI Iris
Copyright 1988-91 Wolfram Research, Inc.
 -- GL graphics initialized --

In[1] := <<OOGL.m
 
In[2] := Plot3D[Sin[x + Sin[y]], @{x,-2,2@},@{y,-2,2@}]

Out[2] := -Graphics3D-
@end example
@noindent
This displays graphics in the usual Mathematica way here.
@example
In[3] := WriteOOGL["math.oogl", %2]

Out[3] := -Graphics3D-
@end example
@noindent
This displays nothing new but writes the file @file{math.oogl}.
You can now load that file into Geomview on any computer.  Alternately,
you can use the @code{Geomview} command to start up a copy of Geomview
from within Mathematica.
@example
In[5] := Geomview[%2]

Out[5] := -Graphics3D-
@end example


@comment ================================================================
@node Geomview.m,RenderMan,OOGL.m,Mathematica
@section Using Geomview as Mathematica's Default 3D Display

The package @file{Geomview.m} arranges for Geomview to be the
default display program for 3D graphics in Mathematica.  To
load it, give the command @code{<< Geomview.m} to Mathematica.
Thereafter, whenever you display 3D graphics with @code{Plot3D}
or @code{Show}, Mathematica will send the graphics to Geomview.

Loading @file{Geomview.m} implicitly loads @file{OOGL.m} as well, so you
can use the @code{Geomview} and @code{WriteOOGL} as described above
after loading @file{Geomview.m}.  You do not have to separately load
@file{OOGL.m}.
@example
% math
Mathematica 2.0 for SGI Iris
Copyright 1988-91 Wolfram Research, Inc.
 -- GL graphics initialized --

In[1] := <<Geomview.m

In[2] := Plot3D[x^2 + y^2, @{x, -2, 2@}, @{y, -2, 2@}]

Out[2] := -SurfaceGraphics-
@end example
@noindent
This invokes geomivew and loads the graphics object into it.
@example
In[3] := Plot3D[@{x*y + 6, RGBColor[0,x,y]@}, @{x,0,1@}, @{y,0,1@}]

Out[3] := -SurfaceGraphics-
@end example
@noindent
This replaces the previous Geomview object by the new object. 
@example
In[4] := Geomview[@{%2,%3@}]

Out[4] := @{-SurfaceGraphics-, -SurfaceGraphics-@}
@end example
@noindent
This displays both objects at once.  You also can have more than one
Mathematica object at a time on display in Geomview, and have separate
control over them, by using the @code{Geomview} command with a name,
@xref{OOGL.m}.
@example
In[5] := Graphics3D[ @{RGBColor[1,0,0], Line[@{ @{2,2,2@},@{1,1,1@} @}] @}]

Out[5] := -Graphics3D-

In[6] := Geomview["myline", %5]
@end example
@noindent
This addes the @code{Line} specified in @code{In[5]} to the existing
Geomview display.  It can be controlled independently of the
"Mathematica" object, which is currently the list of two plots.
@example
In[7] := <<GL.m
@end example
@noindent
If you're on an SGI, loading @code{GL.m} returns Mathematica to its
usual 3D graphics display.  To do this on a NeXT you should load
@code{PSDirect.m} if you are using Mathematica in a notebook, or
@code{NeXT.m} if you invoked Mathematica from a shell.  The following
plot will appear in a normal static Mathematica window.
@example
In[8] := ParametricPlot3D[@{Sin[x],Sin[y],Sin[x]*Cos[y]@}, @{x,0,Pi@},@{y,0,Pi@}]

Out[8] := -Graphics3D-
@end example
@noindent
We can return to Geomview graphics at any time by reloading @file{Geomview.m}.
@example
In[9] := <<Geomview.m

In[10] := Show[%8]

Out[10] := -Graphics3D-

In[11] := ParametricPlot3D[
	   @{(2*(Cos[u] + u*Sin[u])*Sin[v])/(1 + u^2*Sin[v]^2),
	   (2*(Sin[u] - u*Cos[u])*Sin[v])/(1 + u^2*Sin[v]^2),
	   Log[Tan[v/2]] + (2*Cos[v])/(1 + u^2*Sin[v]^2)@},
	  @{u,-4,4@},@{v,.01,Pi-.01@}]

Out[11] := -Graphics3D-
@end example
This last plot is Kuen's surface, a surface of constant negative
curvature.  Parametrization from Alfred Gray's @emph{Modern Differential
Geometry of Curves and Surfaces} textbook.

@comment ================================================================
@node RenderMan,Remote Display,Geomview.m,Mathematica
@section Using Mathematica to generate RenderMan files

In addition to the @code{WriteOOGL} and @code{Geomview} commands
described above, the package @file{OOGL.m} also defines the command
@code{WriteRIB} which writes a 3D graphics object to a RenderMan RIB
file:  @code{WriteRIB[@var{file}, @var{graphics}]} writes @var{graphics}
to file @var{file}.  RenderMan is a commercial rendering system available
from Pixar, Inc., which can produce extremely high quality images.
@example
In[1] := <<OOGL.m

In[2] := <<Graphics/Polyhedra.m

In[3] := Graphics3D[Cube[]]

Out[3] := -Graphics3D-

In[4] := WriteRIB["cube.rib", %3]

Out[4] := -Graphics3D-
@end example
@noindent
This generates the file @file{math.rib}.  This is a ready-to-render RIB
file of the given geometry, using a default camera position, lighting,
and the ``plastic'' shader. In a shell window, type @code{render
cube.rib} to generate the image file @file{mma.tiff}. Of course, you
need to have RenderMan installed for this to work. A shortcut to render
from inside Mathematica is @code{WriteRIB["!render", foo]}.@refill

@code{WriteRIB} works by first converting the Mathematica graphics
object to OOGL format using @code{WriteOOGL} and then calls an external
program @file{oogl2rib} to convert OOGL to RIB format.  The
oogl2rib program takes several options which you can specify in a
string as an optional third argument to @code{WriteRIB}.  The default
option string is @code{" -n mma.tiff "}, which indicates that the RIB
file should generate a rendered TIFF file named @file{mma.tiff}.  A
particularly useful option is @code{-g}, which tells oogl2rib to
convert only the geometry into a RIB fragment. You can insert that
fragment into a full RIB file of your own making with camera positions
and shaders of your choice, to harness the full power of RenderMan.

The full usage of oogl2rib is:
@example
oogl2rib [-n @var{name}] [-B @var{r},@var{g},@var{b}] [-w @var{width}] [-h @var{height}] [-fgb] [@var{infile}] [@var{outfile}]
@end example
@noindent
By default it reads from stdin and writes to stdout.
Either @var{infile} or @var{outfile} may be @file{-}, which means
use stdin/stdout.  The options are:
@table @code

@item -n @var{name}
Use @var{name} for the name of the rendered TIFF file (default
"geom.tiff") or framebuffer window (default "geom.rib").

@item -B @var{r},@var{g},@var{b}
Use background color (@var{r},@var{g},@var{b}).  Each component ranges
from 0 to 1. Default: none.

@item -w @var{width} -h @var{height}
Rendered frame will be @var{width} by @var{height} pixels.

@item -f
RIB file renders to on-screen framebuffer instead of TIFF file.

@item -g
Output only the geometry in RIB format.

@item -b
Output only a Quick Renderman clip object.  Ignores -nBwhf.

@end table


@comment ================================================================
@node Remote Display,Networked Geomview,RenderMan,Mathematica
@section Using Geomview and Mathematica on Different Computers

It is possible to use Geomview to display graphics generated by
Mathematica running on a different computer.  If each computer is either
an SGI or a NeXT and they are networked together, you can tell
Mathematica to use a remote host for Geomview graphics.  If you want to
use Mathematica on a computer that is not networked with your Geomview
computer, or on any kind of computer other than an SGI or a NeXT (for
example a PC or a Mac), you can write out @emph{chunk} files in
Mathematica which you transfer to the Geomview computer and then
translate to OOGL format.

@menu
* Networked Geomview::	Using a networked Geomview host.
* Chunks::		Transporting Mathematica files to Geomview by Hand.
@end menu

@comment ----------------------------------------------------------------
@node Networked Geomview,Chunks,Remote Display,Remote Display
@subsection Using a Networked Geomview Host

The @code{Geomview} command looks at the @code{DISPLAY} or
@code{REMOTEHOST} environment variables to try to determine if you are
logged in from another computer.  If either of these indicates that you
are, @code{Geomview} will attempt to run Geomview on that
computer.  In order for this to work, your network must be configured
such that the Mathematica computer can successfully @code{rsh} to the
Geomview computer without giving a password.

You can also explicitly set the @code{DisplayHost} option to the
@code{Geomview} command to a string which is the desired hostname, for
example:
@example
In[1] := << OOGL.m

In[2] := Plot3D[Sin[x + Sin[y]], @{x,-2,2@},@{y,-2,2@}]

Out[2] := -Graphics3D-

In[3] := Geomview[%3, DisplayHost->"riemann"]
@end example
@noindent
This displays the graphics @code{%3} on the remote host named
@code{riemann}.@refill

@code{Geomview} recognizes the string @code{"local"} as a value for
@code{@$DisplayHost}; it forces the graphics to be displayed on the local
machine.@refill

In addition to knowing the name of the machine you want to run Geomview
on, the @code{Geomview} needs to know the type of that machine (SGI or
NeXT).  By default, @code{Geomview} assumes that it is the same kind of
computer as the one you are running Mathematica on.  The @code{MachType}
option lets you explicitly specify the type of the @code{DisplayHost}
computer; it should be one of the strings @code{"sgi"} or
@code{"next"}.@refill

You can use @code{SetOptions} to change the default @code{DisplayHost}
and @code{MachType}.  For example,
@example
In[4] := SetOptions[Geomview, DisplayHost->"riemann", MachType->"sgi"]
@end example
@noindent
arranges for @code{Geomview} to run Geomview on an SGI workstation named
@code{riemann}.@refill

@comment ----------------------------------------------------------------
@node Chunks,Package Details,Networked Geomview,Remote Display
@subsection Transporting Mathematica Files to Geomview by Hand

The auxilliary function @code{WriteChunk} is for those who can only use
Mathematica on a non-Unix machine (Mac, PC) or a Unix machine that is
not on a network with an SGI or NeXT.  @code{WriteChunk[@var{file},
@var{graphics}]} generates a file named @var{file} which contains the
graphics object @var{graphics} in the format accepted by
@file{math2oogl}.@refill

You can transfer that file to a computer that has Geomview installed on
it and then use the programs @file{math2oogl}, @file{oogl2rib}, and
@file{geomview} directly from the shell.  These programs are distributed
in the @file{bin/sgi} (on SGIs) or @file{bin/next} (on NeXTs)
subdirectory of the Geomview directory, and may have been installed so
that they are on your @code{path}. 

@example
In[1]:= <<OOGL.m

In[2]:= Plot3D[ Sin[x + Sin[y]], {x,-2,2}, {y,-2,2} ]

Out[2]= -SurfaceGraphics-

In[3]:= WriteChunk["mychunk",%2]
@end example
@noindent
This writes the file @file{mychunk} which contains a description
of the graphics object.  You can then transfer this file to an SGI or
NeXT and type
@example
math2oogl < mychunk > mma.oogl
@end example
@noindent
to convert it to the OOGL file @file{mma.oogl} which you can then view
using Geomview. This is the equivalent of the @code{WriteOOGL} command. 

For a result equivalent to the @code{Geomview} or @code{Show}
commands, type
@example
math2oogl -togeomview Mathematica geomview < mychunk
@end example
@noindent

The @code{WriteRIB} command can be emulated from the shell as
@example
math2oogl < mychunk | oogl2rib -n mma.tiff
@end example
@noindent




@comment ================================================================
@node Package Details,Package Installation,Chunks,Mathematica
@section Details of the Mathematica->Geomview Package

The @file{OOGL.m} package uses the external program @file{math2oogl} to
convert @code{Graphics3D} objects to OOGL format, because a compiled
external program is able to do this conversion many times faster than
Mathematica.

The converter will sometimes handle colored SurfaceGraphics objects
correctly that Mathematica does not handle correctly, which means that
Geomview[object] sometimes works where Show[object] will give errors.

The converter supports the @code{Polygon}, @code{Line}, and @code{Point}
graphics primitives, @code{RGBColor Graphics3D} directives, and
@code{SurfaceGraphics} objects with or without @code{RGBColor}
directives, and lists of any combination of these. It silently ignores
all other directives.

The Mathematica to RenderMan conversion is actually a two-step process:
Mathematica->OOGL (math2oogl), and OOGL->RenderMan (oogl2rib). The
math2oogl program has only been tested on SGIs and NeXTs, but could
theoretically compile on any machine. The oogl2rib program depends on
the OOGL (Object Oriented Graphics Language) libraries, which now only
exist on SGI and NeXT machines.

In the @code{WriteOOGL} and @code{WriteRIB} commands, filename can
either be a string containing a filename, an @code{OutputStream} object,
or a string starting with a @code{!} to send the output to a command.
Object can be a @code{Graphics3D} object, a @code{SurfaceGraphics}
object, or a list of these.@refill

The packages work best with Mathematica 2.0 or better.  With version 1.2,
the Geomview display is always on the local host. 

@comment ================================================================
@node Package Installation,Installation,Package Details,Mathematica
@section Installing the Mathematica Packages

If Geomview is properly installed on your system according to the
instructions in @xref{Installation}, then the Mathematica-to-Geomview
packages should work as described here; there should be no need for
additional installation procedures.  In practice, however, it is
sometimes necessary to taylor the installation of the Mathematica
packages and/or of Geomview itself to suit the needs of a particular
system.  This section contains details about how the installation works;
if the Mathematica-to-Geomview connection does not seem to work for you
after following the Geomview installation procedure, consult this
section to see what might need to be fixed.

In this section, the phrase @emph{Geomview installation} refers any of
the procedures in @xref{Installation}.  The way the Mathematica packages
work and are installed is the same regardless of whether you have
one of the binary distributions or the source distribution.

@enumerate

@item
The relevant mathematica files are @file{OOGL.m}, @file{Geomview.m}, and
@file{BezierPlot.m}; Mathematica must be able to find these files.  They
are distributed in the @file{@$GEOMROOT/mathematica} subdirectory of the
binary distributions, and in the
@file{@$GEOMROOT/src/bin/geomutil/math2oogl} subdirectory of the source
distribution.  These files need to be in a directory that is on
Mathematica's search path.  You can look at the value of the
@code{@$Path} variable in a Mathematica session on your system to see a
list of the directories on Mathematica's search path.

The Geomview installation procedure puts copies of the Mathematica
packages into a directory that you specify (@code{MMAPACKAGEDIR}).  This
should ensure that Mathematica can find them.  Alternately, you could
arrange to append the pathname of the Mathmematica package subdirectory
of the Geomview distribution to the @code{@$Path} variable each time you
run Mathematica.

@item
The package @file{OOGL.m} needs to be able to invoke the programs
@file{geomview}, @file{math2oogl}, and @file{oogl2rib}.  The Geomview
installation procedure installs these programs into a directory that you
specify for executables (@code{BINDIR}).  Ideally, this directory should
be on your shell's @code{@$path}.  More specifically, it should be on
the @code{@$path} of the shell in which Mathematica runs; the directory
@file{/usr/local/bin} is usually a good choice.  You can see the list of
directories on this path by giving the command @code{!echo @$path} in
Mathematica.

If for some reason you can't arrange for @file{geomview},
@file{math2oogl}, and @file{oogl2rib} to be in a directory on the
shell's @code{@$path}, you can modify @file{OOGL.m} to cause it to look
for them using absolute pathnames.  To do this, change the definitions
of the variables @code{@$GeomviewPath} and @code{@$GeomRoot}, which are
defined near the top of the file.  Change @code{@$GeomviewPath} to the
absolute pathname of the @file{geomview} shell script on your system.
Change @code{@$GeomRoot} to the absolute pathname of the
@file{@$GEOMROOT} directory on your system.  If you do this, you should
also make sure there are copies of @file{geomview}, @file{math2oogl},
and @file{oogl2rib} in the @file{@$GEOMROOT/bin/sgi} (on an SGI) or
@file{@$GEOMROOT/bin/next} (on a NeXT) directory.

@item
The @file{geomview} shell script, which @file{OOGL.m} uses to invoke
Geomview, needs to be able to find the geomview executable file (which
is called @file{gvx} on the SGI and @file{Geomview.app/Geomview} on the
NeXT).  The Geomview installation procedure should have been taken care
of this, but if your Mathematica session doesn't seem to be able to
invoke Geomview, it's worth double-checking that the settings in the
@file{geomview} script are correct.

@end enumerate

@comment ****************************************************************
@node Installation,SGI Binary Installation,Package Installation,Top
@chapter Installation

What you do to install Geomview depends on which kind of computer you
have (SGI or NeXT) and on whether you have the source distribution or
the binary distribution.

In general, if you don't care about looking at Geomview's source code,
you should get the binary distribution.  Its installation is much easier
and quicker than that for the source code.

@menu
* SGI Binary Installation::   Installing the SGI Binary Distribution.
* NeXT Binary Installation::  Installing the NeXT Binary Distribution.
* Source Code Installation::  Compiling and Installing the Source Code Distribution.
* Obtaining::		Obtaining Geomview.
@end menu

@comment ================================================================
@node SGI Binary Installation,SGI Binary Detail,Installation,Installation
@section Installing the SGI Binary Distribution

If you have just obtained a copy of the SGI binary distribution (file
@file{geomview-sgi.tar.Z}), you should be able to run Geomview and make
use of most of its features immediately after unpacking it by
@code{cd}'ing to the directory that it is in and typing @code{geomview}.

In order to fully install Geomview so that you can run it from any
directory and use all of its features, follow the steps in this section.
In particular, you must go through this installation procedure in order
to use Geomview to display Mathematica graphics.

Geomview is distributed in a directory that contains various files and
subdirectories that Geomview needs at run-time, such as data files and
external modules.  It also contains other things distributed with
Geomview, such as documentation and (in the soure-code distribution)
source-code.  We refer to the root directory of this tree as the
@file{@$GEOMROOT} directory.  This is the directory called @file{Geomview}
that is created when you unpack the distribution file.

To install Geomview on your system, arrange for the @file{@$GEOMROOT}
directory to be in a permanent place.  Then, in a shell window,
@code{cd} to that directory and type @code{install}.  This runs a shell
script which does the installation after asking you several questions
about where you want to install the various components of Geomview.

After running the @code{install} script you should now be able to run
Geomview from any directory on your system.  (You may need to give the
@code{rehash} command in any shells on your computer that were started
up before you did the installation.)


The @file{install} script puts copies of the files in
@file{@$GEOMROOT/bin/sgi} and @file{@$GEOMROOT/man} into the directories
you specified for executables and man pages, respectively.  Once you
have done the installation you can cut down one the disk space required
by Geomview by removing some files from these directories, since copies
have been installed elsewhere.  You should first test that your
installed Geomview works properly because once you remove these files
from their distribution directories you will not be able to do the
installation again.

In particular, the files you can remove are

@table @asis

@item @file{@$GEOMROOT/bin/sgi}:
Remove all files from here except @file{gvx}, which is the geomview
executable file.  DO NOT REMOVE @file{gvx}.  It is not installed
elsewhere.

@item @file{@$GEOMROOT/man}:
You can remove all the files in this directory.

@end table


@comment ================================================================
@node SGI Binary Detail,NeXT Binary Installation,SGI Binary Installation,SGI Binary Installation
@subsection Details of the SGI Binary Installation

The @code{install} script should be self-explanatory; just run it and
answer the questions.  This section gives some details for system
administrators and other users who may want to know more about the
installation. 

The installation is actually done by @code{make}; the @code{install}
script queries the user for the settings of the following @code{make}
variables and then invokes @code{make install}.

@table @asis

@item @code{GEOMROOT}:
the absolute pathname of the Geomview root directory.  The
@code{geomview} shell script, which is what users invoke to run
Geomview, uses this to set various environment variables that Geomview
needs.  It is very important that this be an @emph{absolute} pathname
--- i.e. it should start with a '/'.

@item @code{BINDIR}:
a directory where executable files are installed.  The @code{geomview}
shell script goes here, as well as various other auxiliary programs that
can be used in conjunction with @code{geomview}.  This should be a
directory that is on users' @file{@$path}.  These auxiliary programs are
distributed in the @file{@$GEOMROOT/bin/sgi} directory; if you specify
this directory for @code{BINDIR}, they are left in that directory.

@item @code{MANDIR}:
a directory where Unix manual pages are installed.  These are
distributed in the @file{@$GEOMROOT/man} subdirectory; if you specify
this directory for @code{MANDIR}, they are left in that directory.

@item @code{MMAPACKAGEDIR}:
a directory where Mathematica packages are installed.  This should be a
directory that Mathematica searches for packages that it loads; you can
see what directories your Mathematica searches by looking at the value
of the @code{@$Path} variable in a Mathematica session.  The
installation process will install some packages there which allow you to
use Geomview to display Mathematica graphics.  These packages are
distributed in the @file{@$GEOMROOT/mathematica} subdirectory; if you
specify this directory for @code{MMAPACKAGEDIR}, or if you specify the
empty string for @code{MMAPACKAGEDIR}, the packages are left in that
directory.  For more details about the way these Mathematica packages
connect to Geomview, @pxref{Package Installation}.

@end table

@comment ================================================================
@node NeXT Binary Installation,NeXTStep Binary Detail,SGI Binary Detail,Installation
@section Installing the NeXT Binary Distribution

@enumerate

@item
If you have just obtained a copy of the NeXTStep binary distribution
(file @file{geomview-next.tar}), you can unpack it by double-clicking on
it in the Workspace.  This will open up a File Viewer panel showing,
among other things, a NeXT Installer package called @file{Geomview.pkg}.


@item
The first thing you should do is double-click on @file{Geomview.pkg} to
invoke the NeXT Installer.  You will be asked where you want to install
it; typically it should go in @file{/LocalApps} or in @file{~/Apps} in
your home directory.  You should now be able to run Geomview and make
use of most of its features by double-clicking on the installed
@file{Geomview.app} icon.

@item
There are some aspects of the installation, however, that the NeXT
Installer can't handle.  In order to fully install Geomview so that you
can use all of its features, you should run the @file{install} script in
the @file{Geomview.app} directory. In particular, you must go through
this installation procedure in order to use Geomview to display
Mathematica graphics.

To run the @file{install} script you can open @file{Geomview.app} in the
Workspace by selecting it and picking @code{File->Open as Folder} from
the Workspace menu.  This will pop up a File Viewer panel showing the
contents of @file{Geomview.app}.  Scroll down to the file named
@file{install}, and double-click on it.  This will open a terminal
window and run the script in that window.  Alternately, you can open a
terminal window yourself, cd to @file{Geomview.app}, and run
@file{install} there.

The @file{install} script does the installation after asking you several
questions about where you want to install the various components of
Geomview.  After running the @code{install} script, Geomview is
completely installed.  If in the future you move @file{Geomview.app} to
some other location you should run @file{install} again.

@item
This step is optional.  Geomview's example data files are in the
@file{Geomview.app/data} directory.  If you are on a network with both
SGI workstations and NeXTStep workstations, and you want to install
Geomview to run on both, you can save disk space by having the two
installations share a common data directory.  To do this, decide on a
location for the data directory and copy it there if it isn't there
already (a good choice would be to leave it in the @file{@$GEOMROOT}
directory in your SGI Geomview installation).  Then edit the file
@file{Geomview.app/CONFIG.gv} to change the setting of the variable
@code{GEOMVIEW_DATA} to point to this directory (there are comments in
the file telling you what to do).  You can then remove the data
directory from @file{Geomview.app}.

@end enumerate

To run geomview, double-click on @file{Geomview.app} from the workspace,
or type @code{open Geomview.app} from the appropriate directory, or type
@code{geomview} from a shell window.

More Geomview documentation is in the @file{Geomview.app/doc}
subdirectory.  In particular, a copy of the manual is there.

The @file{install} script puts copies of the files in
@file{Geomview.app/bin/next} and @file{Geomview.app/man} into the
directories you specified for executables and man pages, respectively.
Once you have done the installation you can cut down one the disk space
required by Geomview by removing all the files in these directories,
since copies have been installed elsewhere.  You should first test that
your installed Geomview works properly because once you remove these
files from their distribution directories you will not be able to do the
installation again.

@comment ================================================================
@node NeXTStep Binary Detail,Source Code Installation,NeXT Binary Installation,NeXT Binary Installation
@subsection Details of the NeXTStep Binary Installation

Other than the installation of the @file{Geomview.app} directory, the
installation details of the NeXTStep binary distribution are the same as
for the SGI distribution, @pxref{SGI Binary Detail}.  Note that the
directory referred to in the SGI distribution as @file{@$GEOMROOT}
is the @file{Geomview.app} directory in the NeXTStep distribution.

@comment ================================================================
@node Source Code Installation,Obtaining,NeXTStep Binary Detail,Installation
@section Compiling and Installing the Source Code Distribution

The main reason to get the source code distribution is to look at and/or
work with the source code.  If you are only concered with @emph{using}
Geomview it is better to get the binary distribution.  It takes anywhere
from 15 minutes to 1.5 hours to compile the entire source distribution,
depending on what kind of computer you have.

Let @file{@$GEOMROOT} denote the full pathname of the Geomview source
code directory; this is the directory called @file{Geomview} that is
created when you unpack the distribution.  This directory contains the
Geomview source code as well as various other files and subdirectories
that Geomview needs when it runs.

Before doing any compilation you should edit the file
@file{@$GEOMROOT/makefiles/mk.site.default}.  This file defines some
@code{make} variables which specify your local configuration.  This
includes the pathnames of the directories into which Geomview will be
installed, and possibly some other settings as well.  There are comments
in the file telling you what to do.  This file is included by every
Makefile in the source tree, so the settings you specify here are used
throughout the source.

If you will be compiling for both SGI and NeXT, you can do both in the
same directory tree.  By default the Makefiles are set up to put the
objects files, libraries, and executables in directories which depend on
the type of computer, so the two architectures will not interfere with
each other.  The Makefiles use a variable called @code{CPU} to determine
the type of machine. Before doing any compilation you must arrange for
this variable to have a value.  There are two ways you can do this.

@enumerate

@item
If you will always be compiling Geomview on the same type of computer
(SGI or NeXT), edit the file @file{@$GEOMROOT/makefiles/Makedefs.global}
to set the @code{CPU} variable to either @code{iris4} or @code{NeXT}.
The comments near the top of that file will tell you where to do this.

@item
If you will be compiling on both types of computers you can set a shell
environment variable named @code{CPU} to either @code{iris4} or
@code{NeXT}, and the Makefiles will inherit the value from the
environment.  The script @file{@$GEOMROOT/config} determines which kind
of computer you are on and sets this variable accordingly.  To use this
script, type @code{source config} in the (assuming a C-shell type shell)
in the @file{@$GEOMROOT} directory shell in which you plan to do the
compilation.  Or you can set the variable directly; it should be either
@code{NeXT} or @code{iris4}.  You will need to do this in every shell in
which you plan to do compilation.

Alternately, you could modify your shell initialization file
(@file{.cshrc} or whatever) to set @code{CPU} appropriately.

@end enumerate

@noindent
Note that many of the Makefiles refer to a variable called @code{MACHTYPE}
to determine the type of machine.  This is set to either @code{sgi} or
@code{next}, depending on the value of @code{CPU}.

Once you have configured your source tree by editing the files as
described above and setting the @code{CPU} variable, you can compile and
install Geomview by typing @code{make install} in the @file{@$GEOMROOT}
directory.  You can also type @code{make all}, or equivalently just
@code{make}, to compile without installing, and then type @code{make
install} later to install.

You can use these same @code{make} comands in any subdirectory in the
tree to recompile and/or install a part of Geomview or a module.

If you want to compile fat binaries under NeXTStep 3.1, before doing any
compilation edit the file @file{@$GEOMROOT/makefiles/mk.next} to
uncomment a particular line there.  There are comments in the file
telling you which line to uncomment.

If you want to modify the complier flags used during compilation, edit
the file @file{@$GEOMROOT/makefiles/Makedefs.global}; the @code{COPTS}
variable specifies the flags passed to the C compiler (cc).

@comment =============================================================
@node Obtaining,Function Index,Source Code Installation,Installation
@section Obtaining Geomview

Geomview is available free via anonymous ftp from Internet host
@file{geom.umn.edu}, IP address 128.101.25.35.  The Geomview
distribution files are in the @file{pub/software/geomview} subdirectory.
They are all tar archive files (@file{.tar} or @file{.tar.Z} files), so
you should use binary mode in ftp for transferring them to your site.

The main files are

@table @asis

@item @file{geomview-sgi.tar.Z}
The SGI binary distribution. Contains executables for running
on any Silcon Graphics IRIS workstation, plus documentation
and example files.

@item @file{geomview-next.tar}
The NeXTStep binary distribution.  This contains fat binaries which will
run on either a NeXT workstation running NeXTStep 3.0 or 3.1, or a 486
PC running NeXTStep 3.1.  Also contains documentation and example files.
This {.tar} file is not compressed because it contains the distribution
compressed into a NeXT Installer package, and further compression
actually increases the size of the file.  To unpack
@file{geomview-next.tar} on a NeXT, simple double-click on it in the
Workspace.@refill

@item @file{geomview-src.tar.Z}
The source code distribution; contains source code so you can compile
Geomview and the distributed external modules on either an SGI or on a
NeXT workstation running NeXTStep 3.0 or 3.1, or a 486 PC running
NeXTStep 3.1.  Also contains documentaion and examples files.

@end table

Each of the above archive files contains the entire distribution:
executables or source for Geomview itself, plus all distributed external
modules, example data files, and documentation.  These archive files are
therefore rather large.  If you do not have enough disk space on your
workstation for the entire distribution, various pieces of the
distribution are available separately in the
@file{pub/software/geomview/pieces} subdirectory.  See the file
@file{README} in that directory for details.

After retrieving any of the distribution archive files, you can
unpack it with a command like the following
@example
% uncompress < geomview-sgi.tar.Z | tar xvopf -
@end example
@noindent
This will unpack the contents of the archive file into
a subdirectory named @file{Geomview}.  Once unpacked, you
can delete the archive file.

The following is a sample ftp session for retreiving and unpacking the
SGI binary distribution.  After unpacking, see the file @file{README}
for more information.

@example
artin% ftp geom.umn.edu
Connected to geom.umn.edu.
220 cameron FTP server (Version 5.88 Thu Jun 25 16:41:41 CDT 1992) ready.
Name (geom.umn.edu:mbp): anonymous
331 For password please enter your e-mail address or name and institution.
Password:mbp@@geom.umn.edu

230 Guest login ok, access restrictions apply.
ftp> cd pub/software/geomview
250 CWD command successful.
ftp> binary
200 Type set to I.
ftp> get geomview-sgi.tar.Z
200 PORT command successful.
150 Opening BINARY mode data connection for geomview-sgi.tar.Z (5815980 bytes).
226 Transfer complete.
local: geomview-sgi.tar.Z remote: geomview-sgi.tar.Z
5815980 bytes received in 28.67 seconds (1.98e+02 Kbytes/s)
ftp> quit
221 Goodbye.
artin% ls -l
total 5680
-rw-rw-r--  1 mbp      5815980 Aug 19 16:38 geomview-sgi.tar.Z
artin% uncompress < geomview-sgi.tar.Z | tar xvopf -
x ./CHANGES, 16910 bytes, 34 tape blocks
@dots{}
artin% rm geomview-sgi.tar.Z
@end example

@comment @comment ****************************************************************
@comment @node General Index,Function Index,Installation,Top
@comment @unnumbered General Index
@comment 
@comment @printindex cp

@comment ****************************************************************
@node Function Index, ,Obtaining,Top
@unnumbered Function Index

@printindex fn

@comment ****************************************************************

@contents

@bye
